Rotate parts of model programatically? [FIXED]

Hi there,



I am working on a ship simulator and are wondering how to import / build my models. As for now, I have a destroyer sailing on the waves, but this is just a ship containing of one single mesh.



http://www.youtube.com/watch?v=IHgq8BSSZmchttp://www.youtube.com/watch?v=IHgq8BSSZmc



Now I need to be able to set rotation and elevation of the guns (and other parts). I am working on a new model and my question is whether I have to model the hull and the guns as separate objects (using Blender) and import them seperately, or can I model them as separate objects in Blender and import them as 1 asembly into JME? In case of the latter, how can I rotate the sub-parts, like guns?

In the past I made the entire ship in Blender, consisting of all different objects and in JME I imported each object (hull, gun, rudder) and positioned them with code. This made it very easy to rotate parts, but I am not sure if this is the right way to go.

If I understand you correctly, you need to use Nodes. Basically, create a new Node, and attach all the ship’s objects to it. Then position them as you want. When you rotate the Node, everything should rotate.

Thanks,



That’s what I did in the past as well. I just wanted to know whether it was possible to do this without importing diferent models for all the ships parts. I can imagine the following structure:



ship

…hull

…superstructure

…5-inch-gun_A

…5-inch-gun-turret_A

…5-inch-barrel_A

…5-inch-gun_B

…5-inch-gun-turret_B

…5-inch-barrel_B



All nodes to be imported as .obj (or other format) and to be positioned in JME in the ‘ship-node’. After that, I can easily rotate the guns and barrels. I am just thinking if it it possible to create this same structure in Blender (maybe apply a skeleton?) and import the entire ship as one .ogre-file. Then, in JME, can I adress and rotate the barrel, for instance?

If you create a single model in blender - then apply a different material to each separate part of the ship…then when you import the model the importer will give you a single node and then inside it separate geometries for each part of the ship.



Open the j3o and if you click on each geometry inside the scene composer you can see wireframe highlighting each section. Rename them to something meaningful.



Now when you load the model you can extract the node for the ship. Inside you will have all the parts of the ship as separate geometries but correctly positioned with each other. You can rotate (or even move) each geometry freely inside the node and all world conversions are handled for you…

2 Likes

Now THAT sounds like something usefull. I will give it a try tonight. This could be what I am looking for.

Okay, I have managed to get the .obj (with different materials for each important detail in Blender) converted to a .j3o and indeed, I can see the individual spatials in the scene composer, as children of the ships node. However, I can’t seem to be able to adress these spatials. Here is how I load the ships model (spatShip = Spatial, ship = Node)):



[java]spatShip = myAssetManager.loadModel(“Models/Fletcher/Fletcher.j3o”);

spatShip.scale(scale);

ship.attachChild(spatShip);

spatShip.setMaterial(myAssetManager.loadMaterial(“Materials/Fletcher/Hull.j3m”));[/java]



And I expected to get one of the ships details with something like spatShip.getChild(Rudder), but a spatial does not have this 'getChild() option. So, I tried to give the ‘root-node’ of the .j3o in the scene composer some childs (nodes) and dragged the spatials into these nodes (so a node named rudder with in it the spatial called ‘rudder’). But things are getting a little bit messy like this (and obviously, it still does not work), so I am not sure where I make the thinking failure…



Well, basically it comes to the following question:

How do I do this, or where am I going wrong:

Now when you load the model you can extract the node for the ship. Inside you will have all the parts of the ship as separate geometries but correctly positioned with each other.

Your code will need to make some assumptions about the contents of your model.



Lets say you have:

model: ship - hull, gun1, gun2



Your code looks something like:



[java]

Node model = (Node)myAssetManager.loadModel("Models/Fletcher/Fletcher.j3o");

Node ship = (Node)model.getChild("ship");

Geometry hull = (Geometry)ship.getChild("hull");

Geometry gun1 = (Geometry)ship.getChild("gun1");

Geometry gun2 = (Geometry)ship.getChild("gun2");

[/java]



(You could verify the types before casting but its pretty pointless since its your model and if the structure is wrong everything is going to fall over later on anyway!)

1 Like

Ship is now your base node that you add to your scene, then the geometry objects inside it are the components of the ship. What I generally do is have a Ship class that knows about the model and loads the model, separates the geometry, etc for you - then store the references extracted above for easy access later.

Arghhh, casting to ‘Node’! How could I possibly forget that?!?! I have been trying to add spatials, nodes, geometries and what so ever! Sometimes you are just staring for ages and overlook the obvious :frowning:



Thank you, Zarch. I will give it a try tonight!



Btw, I indeed do have a class for the ship in which all the work is done. From the main application, I only call for functions to move and animate the ship in the prePhysicsTick.

Well, that works indeed. But… The individual parts all rotate around the world origin, not around there local origins. Take the rudder, for instance: It is located in Blender near the stern of the ship, in OBJECT MODE I have moved the origin of the rudder to the rudder shaft. After that, I have exported the rudder to .obj and in JME converted it to .j3o. The local Translation (in scene viewer) shows (0,0,0) while the rudder in JME is not in the world origin and applying a local rotation rotates it around the world origin.



Given the fact that the rudder in JME is not positioned in the world origin but in the position where I have put it in Blender, I would say there is something wrong with my origin in Blender. It seems as if the object origin I make in Blender is not exported to the .obj? I export in Blender to .obj with the following settings:


  • Selection Only
  • Apply Modifiers
  • Include Edges
  • Include Normals
  • Write Materials
  • Objects as OBJ Objects
  • Scale: 1.00
  • Forward: -Z Forward
  • Up: Y Up
  • Path Mode: Auto



    Blender version is 2.62.



    When I import only the rudder (after moving the vertices as well as the object origin in Blender to the world origin), I can set a local translation in the scene viewer and apply a local rotation without any problem: The rudder is moved to the given position and rotates around its own axis. I am just struggling why this is not working when the rudder in Blender is not in Blenders world origin.



    Any idea where I might go wrong here?

Just reading a post on a different forum (http://www.alice.org/community/archive/index.php/t-6895.html) which is stating an .OBJ is not able to store multiple origins. Seems like I will have to export to a different file-format.

Hmm, good point. I’d forgotten about that. You would need to create a Node, drop the geometry into that node. Set the offset on the geometry to move it to the node origin then offset on the node to move it back to the geometries position.



If going to do that though you might be better off doing something else - which actually gives you more flexibility in some ways as it would allow sub-components to themselves have sub-components. Someone else with more experience may be able to suggest an improvement on this though.



Remove the guns from the model and just put “anchor points” as a simple square or whatever.



Put the guns/etc in as their own separate models base at 0,0,0.



As an extra step when loading the ship find the anchor points as above. For each one read the local offset (might have to query the vertices) and then delete it. Load the correct model and add it to the ship, apply the local offset from the anchor to the model. The advantage of this is that it would allow the gun models to have their own moving parts as the process can be recursive.



To be honest we’ve reached the limits of my knowledge though as I knew about the blender splitting thing as I’ve used that but I’ve never tried to use it quite the way you are.

I think I will just do what I did in the past:


  1. Model the entire ship in Blender, making different objects for the moving parts.
  2. Export the moving parts as individual OBJ-files.
  3. Export all the non-moving parts as one OBJ-file.
  4. Import the non-moving OBJ-File and use that as the root node of the ship.
  5. Import all the moving parts with the origin at their (local) rotating axis.
  6. Create a TXT-file which holds the positions of the moving parts.
  7. Read the TXT-file and position the moving parts by code.



    This worked in the past and gives you some flexibility when it comes to re-using parts (for instance, the gun could be used on different ships now. Also, I can define in the TXT-file how many guns there will be on the ship).



    Thanks for your help anyway, I have learned from it!

@husky: The OBJ format is not appropriate for your scenario. You will need to use either OgreXML + dotScene format or the jME3 Blender importer.

1 Like

The blender importer should cope nicely once they are all positioned correctly.

1 Like

I got the model imported directly from the BLEND-file (finally), but it seems as if not all of the modifiers are supported yet. I get this error:



Unsupported modifier type: EdgeSplitModifierData



When I remove/apply the Edge Split modifier in Blender, the import goes okay. I do not want to apply the modifier yet however, since I am still working on the model. Is this modifier indeed not supported (yet)?

I’m not sure about that but I’d apply all your modifiers and export to a copy anyway to then do the import.



It makes sure that all the modifiers are applied exactly how blender applies them.





If you are using the latest (2.63) blender you will also need the latest (nightly) JME SDK to handle the imports.

I managed to get the file imported as a .BLEND and now it works. Only thing is I have to apply the modifiers in Blender now, because they are not supported yet by the importer. And since I am still working on the model, this is quite a pain, but I can live with saving a copy of the Blender-file and apply all modifiers in the copy and use the copy in JME for now while working in Blender on the original.



Good thing about the Blender importer is the fact that it automatically gives the objects the names as they had in Blender, so I don’t have to rename every object in the scene viewer. That’s also why I can live with a copy for testing for now, because I do not have to rename all the objects the next time I import an updated model.



So, to wrap up: I am happy :slight_smile:



Thumbs up for Zarch and Momoko Fan!