Developing Game with JME - Mouse Picking issues

Hello,



  I've been developing a game (first-person shooter), and in my simple scenario we have Boxes and Spheres that can be thrown. I also have some Physics in the game by using JPhysx bindings to Ageia Physx.



  I'm using the left mouse click to shoot, and by using the HelloPick example as a base, I'm trying to adapt it to the game. I've got three issues, I hope it is not too basic as I'm working with JME for a few days.



  1) I'm using an aim texture (just like a Sniper aim), as the mouse texture. The problem is that the center of the Texture should be the mouse pointer, so that when shooting takes place, the aim's center really points correctly to the object.



  2) How can I "destroy" the object, so that once it is hit, it is removed from the scene. I can change colors (of the boxes), like the example, but nothing more than this, up to now.



  3) I'm trying to make a Score, so that when an object is hit or missed, I can inform the user how many point he scored.



  I'll attach the code for the game, so that you can see clearly what I'm trying to achieve. The Mouse Picking code is taking place on initMouse () - setting AbsoluteMouse and other details, then in the simpleUpdate() method, where I can pick the distance, and name of the objects and change their colors randomly.



  The complete code for the project, with textures etc… can be downloaded from http://freeunix.com.br/Physx.zip, in case you wish to experiment with it. You'll need Ageia Physx installed, though and AFAIK, Windows too.



    Thanks in advance for any help.



/* That's the main class */
package ra;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.logging.Logger;




import org.lwjgl.LWJGLException;
import org.lwjgl.util.Display;



import util.CapturaMouse;
import util.Objects;
import util.PhysicConsts;
import util.TextureUtil;

import com.JPhysX.JPhysXAdapter;
import com.JPhysX.NxActor;
import com.JPhysX.NxJointFlag;
import com.JPhysX.NxMaterial;
import com.JPhysX.NxParameter;
import com.JPhysX.NxRevoluteJointDesc;
import com.JPhysX.NxScene;
import com.JPhysX.NxSceneDesc;
import com.JPhysX.NxSimulationStatus;
import com.JPhysX.NxVec3;
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.image.Texture;
import com.jme.input.AbsoluteMouse;
import com.jme.input.FirstPersonHandler;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.input.action.InputActionEvent;
import com.jme.input.action.KeyInputAction;
import com.jme.intersection.BoundingPickResults;
import com.jme.intersection.PickResults;
import com.jme.intersection.TrianglePickResults;
import com.jme.math.Matrix3f;
import com.jme.math.Ray;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Controller;
import com.jme.scene.SceneElement;
import com.jme.scene.Skybox;
import com.jme.scene.Spatial;
import com.jme.scene.Text;
import com.jme.scene.TriMesh;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.CullState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.MaterialState;
import com.jme.scene.state.TextureState;
import com.jme.util.TextureManager;
import com.jme.util.resource.ResourceLocatorTool;
import com.jme.util.resource.SimpleResourceLocator;
import com.jmex.audio.AudioSystem;
import com.jmex.audio.AudioTrack;

import examples.HelloMousePick;

public class RVRA extends SimpleGame
{
    // Controle do Mouse, p/ pegar os cliques e fazer placar.
    private AbsoluteMouse am;
    // Cena para a o Physx
    private NxScene physxScene;
    // Lista de "atores" da cena, ou seja, est

I haven't read your source code, it's just too long. So some or all answers might be a bit off.


brenojac said:

  1) I'm using an aim texture (just like a Sniper aim), as the mouse texture. The problem is that the center of the Texture should be the mouse pointer, so that when shooting takes place, the aim's center really points correctly to the object.

Just add offset coordinates to your mouse's screen coords before converting them to world coordinates.

brenojac said:

  2) How can I "destroy" the object, so that once it is hit, it is removed from the scene. I can change colors (of the boxes), like the example, but nothing more than this, up to now.

object.removeFromParent() should do the trick for the jME part. The physics stuff will likely need additional handling, I can't help you with that.

brenojac said:

  3) I'm trying to make a Score, so that when an object is hit or missed, I can inform the user how many point he scored.

Have a look at how BaseSimpleGame initializes the fps display text for info on how to show text.

Thank you very much, hevee and christius, the hints were very useful.



    I've got two other issues and wasnt able to find a solution yet:


  1. The text informing the user's score gets overwritten by the target texture (sniper), when moving the mouse over it. Is there a way to "send the text to front", so that the mouse texture is not above it?


  2. I'd like to get the X, Y coordinates of the object when clicked, so that I can take some decision based on this. Watching the API I saw getWorldCoords(), but it is not close to what I need. 



    any help would be much appreciated, thanks in advance.

Hello Christious,



    For the first problem, I solved it by setting the texture transparently, so that even if it goes over the text, it's still readable.



    The second issue, here's what I mean: I create a Box, using the texture of a guy pointing a gun to the player:



public final void addTargetAt(Vector3f position)

    {

        float sizeX = 5.0f;

        float sizeY = 10.0f;

        float sizeZ = 0.5f;



        Box b = new Box("Target", new Vector3f(), sizeX, sizeY, sizeZ);

        b.setModelBound(new BoundingBox());

        b.updateModelBound();



        rootNode.attachChild(b); // Put it in the scene graph

        NxActor actor = physxScene.createActor(PhysicConsts.getBoxStaticActorDescFor(position.x, position.y, position.z, sizeX, sizeY, sizeZ));

        actors.add(actor);

        objectsMap.put(actor, b);



        TextureUtil.setTexture(display, b, TextureUtil.targetTexture);

    }



  Then, I'd like to conditionally destroy the object from the scene, only if it's hit in certain boundaries, such as the head or the body of the texture. But for that I'd need the coordinates of the spot when clicking the Box. That's why I dont see how the Z coordinate is relevant, because that's pretty much 2D.



  I hope it is clear this time, if its not then please ask again.



best regards,


  • Breno


brenojac said:

Thank you very much, hevee and christius, the hints were very useful.

    I've got two other issues and wasnt able to find a solution yet:

1) The text informing the user's score gets overwritten by the target texture (sniper), when moving the mouse over it. Is there a way to "send the text to front", so that the mouse texture is not above it?




Not sure if zOrder will fix this but I'm pretty sure both the cursor and the text are both rendered in the ortho queue so it should.  You might want to look into adding a zbufferstate (maybe not needed for ortho?) and setting the z order (setZOrder()) on the text and the mouse to see if that has any effect.  Or you can probably check the mouse coordinates and not let the cursor move over the text (reset the mouse coords to the boundary of a box that encloses the text) - if I need to target someone/something and it's behind a text node how am I going to accurately hit it anyway?

brenojac said:

2) I'd like to get the X, Y coordinates of the object when clicked, so that I can take some decision based on this. Watching the API I saw getWorldCoords(), but it is not close to what I need.   

any help would be much appreciated, thanks in advance.


What do you mean by X,Y coords?  Do you mean the X,Y translation in 3D space?  The X,Y coords on an arbitrary grid or board you have created in the scene?  Do you not care about the Z coord?  If you can give some more info it'll be easier to answer your question correctly without having to make guesses.  Thanks.

That does clear things up a bit.  You want the x,y of the intersection point from the mouse pick ray where it hits on the texture.  I would look to implement this a totally different way as I'm not sure you can actually (or certainly not easily) get the information you are looking for.



What I'd do is this -



Build your "target" as a node.  Add your textured box to that node, then add additional boxes and/or spheres or whatever shapes best fit the body/head shapes on your texture.  Position those objects appropriately so that they align the way you want relative to your textured box and set them not to render.  Then do your picking against those objects - if you "pick" the head object, it's a headshot, body object, gutshot, etc.



This is probably (almost certainly) NOT the most efficient way to organize your scenegraph but it should be the easiest and most straightforward to implement and understand quickly since if you're already applying movement/translations to your "target" object, your picking objects will move with it automatically.  Once you get comfortable with this you may want to look at reorganizing your nodes to make the picking more efficient at the cost of possibly adding some complexity in dealing with movement/translations.  If I'm terribly wrong on this I'm sure someone far more versed in jME will correct me (and hence help you).