Point mesh Position buffer and its relation to local translation

As you guys may remember I’m using Mode.Points for suns in my game. They’re setup that way:



[java]

for (int i = 0, j = leafStarsIdx.size(); i < j; i++) {

Mesh sun = new Mesh();

if (leafStarsIdx.get(i).isHomeworld()) {

sun.setPointSize(2f);

} else {

sun.setPointSize(.25f);

}

sun.setBuffer(Type.Position,

3,

BufferUtils.createFloatBuffer(

leafStarsIdx.get(i).getStarCoordinates()));

[/java]



That works beautifully. The problem I’m having right now is that I’m implementing a “targeting” for the closest star in the vicinity of the player’s ship when TAB is hit.



The GalaxyScene (which is an AbstractAppScene) keeps in memory an array of geometries composing the stars in the given sector. It’s setup the following way (which is the continuity of the above code).



[java]

Material mat = new Material(gMgrs.getAssetManager(),

“Common/MatDefs/Misc/Unshaded.j3md”); //NOI18N

mat.setColor(“Color”, leafStarsIdx.get(i).getStarColorForGalaxy()); //NOI18N

starsGeo = new Geometry(“star”

  • leafStarsIdx.get(i).getStarID(), sun); //NOI18N

    BoundingSphere bs = new BoundingSphere(0.05f, leafStarsIdx.get(i).getStarCoordinates());

    starsGeo.setModelBound(bs);

    starsGeo.updateModelBound();

    starsGeo.setMaterial(mat);

    starsGeo.setUserData(“ID”, leafStarsIdx.get(i).getStarID()); //NOI18N

    sceneNode.attachChild(starsGeo);

    }

    [/java]



    Because of the way the Point meshes are implemented (above) I can’t set a local translation to the geometry. If I do, the points will be relocated elsewhere. So what I’d like to do is make a “new” mesh shape, like a sphere if you want, so I can have the best of both worlds, but so far, this hasn’t worked since I have no idea how to go at this.



    There is also an alternative. I can “store” the local translation into a userData, but I’m not too fond of that because it’s a hashmap and slower that just using a getLocalTranslation() directly from the geometry…



    I’m feeling here like I’m missing something. Maybe I’m misunderstanding the Custom Mesh page in the wiki…
1 Like

I’m not clear on why the mesh comes into it. You say: “The problem I’m having right now is that I’m implementing a “targeting” for the closest star in the vicinity of the player’s ship when TAB is hit.”



…which sounds like a game object problem to me. Somewhere you had data that you turned into a visual (the point mesh) and now you want to make a query against that data. I don’t think using the mesh or the scene graph buys you anything special except for trouble… but I don’t know where the original star locations come from.

Ah, forgot to add that I did try to get a distance from the player’s ship to the returned array of geometries, but when using getWorldCoordinates() on it, I always get a 0, 0, 0 vector. I could do multiple casts to get the mesh, the VertexBuffer finally get 3 floats but… Yeah…

1 Like

What “returned array of geometries”? Where did this array of geometries come from?



Do you have one mesh with many points in it or lots of different points meshes?



Either way, I sort of feel like in a proper design that the mesh is irrelevant. From a game-level perspective, you have star, planet, ship positions, etc. that still exist even if you never drew a piece of geometry for them. This is where your game logic should run… which includes queries like “what’s the nearest star?”

@pspeed said:
I don't think using the mesh or the scene graph buys you anything special except for trouble... but I don't know where the original star locations come from.


In this case it's not a necessity to use the scene graph since those point meshes are static and unmoving but in the other scenes (Solar system and Arena) objects are in motion and I need to query the scene graph. But that's besides the point since what is returned is a clone of the data.

The original data comes from an ArrayList which is a data holder for each sector of the galaxy. I guess I could use that, I'd maybe have to twirl one or two new methods... I'd rather use a short-lived clone of the already existing data though. Seems better to do it that way.
1 Like
@pspeed said:
What "returned array of geometries"? Where did this array of geometries come from?

[java]
ArrayList<Geometry> targets = gameState.getAppStateManager().getState(GalaxyScene.class).getStarsGeometry();

//which is...

public ArrayList<Geometry> getStarsGeometry() {
return new ArrayList(Arrays.asList(starsGeo));
}
[/java]
Note that the geometry array is class global only because I need to retrieve it for things like targeting. Once it's been added to the scene node, I don't really need it.


Do you have one mesh with many points in it or lots of different points meshes?

One mesh for each star. But, it's only 1 point. *shrug*


Either way, I sort of feel like in a proper design that the mesh is irrelevant. From a game-level perspective, you have star, planet, ship positions, etc. that still exist even if you never drew a piece of geometry for them. This is where your game logic should run... which includes queries like "what's the nearest star?"

Call me paranoid, but I don't want to expose or at least expose at the minimum, my data holder classes...
1 Like

I’m a big fan of game logic using game objects and visualization classes using visualization objects and there being a giant brick wall (with a little doorway) between them. No good can ultimately come from mixing them.



Anyway… if you have one star per mesh then why not put the star at 0,0,0 and locate the mesh where the star should be?

Stars positions are determined at galaxy generation. Why would I want to put them at 0? Then how am I supposed to know where they’ll be placed in a spiral galaxy or a barred or an elliptical one? All that data is contained in the data holding class. Which is actually a bastardized-hybrid Octree. I don’t think it could even be called that anymore. Anyway…



But I failed to see what all this has to do with my original question though. Is it possible to create a new mesh subclass (like a sphere or a box) using a Point so that I can use location translation getting/setting? That would solve my problem. A hint in the right direction would greatly help. :slight_smile:

1 Like

I am so confused. Making a mesh subclass is trivial so I don’t understand what I’m missing about why it’s hard.



Here is what I think you’ve told me so far:

  1. you have x number of geometries representing x number of stars
  2. each of these geometries has a single-point point mesh.
  3. the geometries are located at 0,0,0 and the point mesh has a point at the stars location



    Do I have something wrong? I used this statement to determine the above: “One mesh for each star. But, it’s only 1 point. shrug



    If so then I don’t understand why the geometries are at 0,0,0 instead of the star location.

Confounding each other. That’s grand! :wink:



All your assertions are right. As for #3, I thought (above) you were telling me to put them at 0,0,0 when you were just repeating me… lol



Here’s what happens.



Since I set the mesh (a Point) with a Type.Position buffer, it’s using THAT to position the mesh. The returned geometry array, when I query it with getWorldLocation() all geometries at 0, 0, 0.



If I also set the geometry to the same location as during the mesh construction, that creates a double that is placed elsewhere in the world. So I end up with two sets of stars at different part of the game world but with the same disposition. If I don’t set the mesh’s Position, I get the geometries (at the wrong place again) but no points in the right area.



My goal is to create a mesh subclass, called Point, that I’ll be able to use on a geometry on which I can call setLocalTranslation(…) and will be displayed at the right place.



Something like

[java]

Point point = new Point();



Geometry pointGeo = new Geometry(“PointStar”, point);



pointGeo.setLocalTranslation(getLocationFromIndex(star));

[/java]



That way I’ll be able to retrieve the position of the stars in the world.



You’re probably thinking here that I should simply use getLocationFromIndex(star). But it doesn’t because that location is arbitrary. I can’t get a world location from that.



Hopefully that’s more understandable. :wink:

1 Like

geometry at 5,5,5, mesh with point at 0,0,0 (what I was asking why you aren’t doing)

…is visually identical to

geometry at 0,0,0, mesh with point at 5,5,5 (what you actually are doing)



The difference is that getting the location is easier in the first case.



I still don’t see the need for a mesh subclass in this case.

Because I want to use it the way you’d use a sphere for example. Or a box. Except it’s a point.



[java] sun.setBuffer(Type.Position,

3,

BufferUtils.createFloatBuffer(

leafStarsIdx.get(i).getStarCoordinates()));

[/java]



The above is the Point. the vector I’m passing the mesh is ITS LOCATION in the world. I know it doesn’t make sense to most to use it this way. Think of it as a storage space if you want. But the fact remains that it’s placed where it needs to be in the world.



The problem is that I can’t retrieve that without great convolutions, so to get that value back, I store the vector in the geometry’s userData until I find a better way. Setting the geometry to the above will display BOTH the point AND the geometry. I understand why it does that, but I want to circumvent it by not setting the point like it is above, but by using the setLocalTranslation in geometry.

1 Like
@madjack said:
Because I want to use it the way you'd use a sphere for example. Or a box. Except it's a point.


Hmmm... every JME Box or JME Sphere I've ever created was at 0,0,0 and then translated with the Geometry.

@madjack said:
[java] sun.setBuffer(Type.Position,
3,
BufferUtils.createFloatBuffer(
leafStarsIdx.get(i).getStarCoordinates()));
[/java]

The above is the Point. the vector I'm passing the mesh is ITS LOCATION in the world. I know it doesn't make sense to most to use it this way. Think of it as a storage space if you want. But the fact remains that it's placed where it needs to be in the world.


Other than being tenacious or "because I've already done it that way"... I still haven't been presented with a good reason. But this may be because you are tightly coupling your game data into your display data... since from the above it sounds like the buffer is your game data. In a Model-View-Controller sense, the buffer is part of the view and your star position is the model. I try to hit your motivations against standard software patterns and come up blank... this may be the source of my inability to "get it": years of experience beating me back into accepted standard approaches.

@madjack said:
The problem is that I can't retrieve that without great convolutions, so to get that value back, I store the vector in the geometry's userData until I find a better way. Setting the geometry to the above will display BOTH the point AND the geometry. I understand why it does that, but I want to circumvent it by not setting the point like it is above, but by using the setLocalTranslation in geometry.


So, let me be sure I understand. You want your code to act like the mesh is at 0,0,0 because you want to be able to move the Geometry but the Geometry won't really move... which means if you ever apply any transforms they won't move either.

And you want to do this so that you can create X number of separate star position buffers instead of just sharing the same one.

More memory, more complexity, all to avoid using things as they were intended. I can't really help find the "best way" anymore because it was so far down another road. I don't even know HOW I would do it, to be honest. There are any number of gotchas with this approach. You'd be better off just grabbing the star position out of the position buffer.

I can tell you that circumventing Geometry's normal local translation will be nothing but trouble. I don't even know what kind of confusion you will create by having getLocalTranslation() not return the same thing as was set in setLocalTranslation()... or if you are actually going to pretend the geometry has moved then I don't know how you are going to tell the mesh that it hasn't... aside from setting its position buffer to 0,0,0.

You are probably better off adding a getStarLocation to a Geometry subclass that just extracts the three floats from the buffer and creates a Vector3f. It is the least unclean.