[SOLVED] saving mesh, creating node from mesh and filesystem issue


photo

Recommended Posts

Hello,

 

I'm having a bit of trouble. In my script I am calling engine.editor.saveMesh(string filename, int id); followed straight by a call of new ObjectMesh(string filename); of the same newly saved mesh name. This works fine the first time I run these together, but on subsequent calls when I'm using the same filename, my new ObjectMesh is recieving the mesh file from 2 calls back of the saveMesh function. I get the feeling that the filesystem is archiving the mesh file, but I'm not up to scratch on how the filesystem really works. So I tried using engine.filesystem.removeFile(string name); but it is always returning zero for me no matter if I delete all nodes with references to that mesh or wether I use the filename with or without the full directory path. Even then if I did get the filesystem to remove it would that even guarantee solving my first problem. Any ideas?

Link to post

I created a test project to highlight my problem, hopefully it makes some sense.

http://dl.dropbox.com/u/12843270/issue.zip

Please note that this code is completely out of context and does not show why I need to do this but it does replicate the issue I am recieving.

 

I think the issue boils down to the fact that engine.editor.saveMesh either doesn't finish or it doesn't get changed on the file system before I try and create an ObjectMesh from it. What I need is a way to wait until I know that the new overwritten mesh will be loaded in correctly.

Link to post

Just had a short view into filesystem source. FileSystem class caches files therefore you don't get latest version written to disc. There are c++ FileSystem::cache/clearFile() for file cache load/removal, but unfortunately these are not exposed to scripting yet.

Link to post

Thanks for looking into that for me. I guess I'll opt for the short term solution of using differing file names but hopefully those functions can be exposed in the near future.

Link to post
  • 2 weeks later...

Actually, FileSystem caching is not to blame for your problem. It's engine cashing - though it is not to blame either :D

 

ObjectMesh is NOT intended to be modified in runtime. When you create a new object mesh, the filename is compared to the list of already loaded meshes and if found, the engine does not reload the mesh from the disk. Instead, it loads it directly from the cache, avoiding the unnecessary load.

 

What can be done in cases like yours:

  • Use ObjectMeshDynamic which is specifically tailored for meshes that are going to be changed in runtime.
  • You can stick to ObjectMesh and simply call render_manager meshes console command. This would reload all currently used meshes so that you get a fresh copy in the cache.

Regarding engine.filesystem.removeFile(), this function simply deletes the file you've requested to be loaded from the pending queue. First, you can append a file to the loading queue with engine.filesystem.loadFile() and then you can cancel your request via engine.filesystem.removeFile(). This function does not actually do anything with the file itself, it just manages the queue.

 

I've updated descriptions of engine.filesystem functions to make them more clear.

 

  1. First engine.filesystem.loadFile() function is called to place the file in the queue for loading.
  2. After that, different operations can be performed:

engine.filesystem.forceFile to load the file immediately

engine.filesystem.removeFile to remove the file from the queue in case there is no need to load it anymore

engine.filesystem.validateFile to check if the file is still pending in the queue or if it has already been loaded

engine.filesystem.checkFile to check if the given file was requested to be loaded via engine.filesystem.loadFile()

 

 

Besides it, in the next update
cacheFile()
and
clearFile()
will be available (though it's hard to say what they can be used for). chacheFile() takes the loaded file and writes into the cache. clearFile() clears the corresponding cache memory block.

  • Like 1
Link to post
  • 3 weeks later...

Unforunately your suggestions have still not solved my problem. Maybe if I tell you exactly what I am trying to achieve it may help.

 

Currently in my world I have a bunch of objects, many of which are scaled which as we know do not play nice with physics. To rectify this, I attempt to create a single unscaled mesh object from all objects in the current world which I would like to make as static physics colliders. To do this I first itrate over each object and their surfaces and create a list of indexed materials so I can reapply them later. Then I add all these objects to an array and use engine.editor.saveMesh to create one mesh out of all these objects, so scaled objects are now relatively unscaled. While doing this I always want to create the mesh with the same name so each time the old one is overwritten.

 

Now here is where the trouble lies, I now simultaneously load that mesh as an Object using the ObjectMesh constructor. I then reapply all the materials to that object using my material list from before. Now the first time I do this it works every time as the mesh has not been loaded. Subsequent loading of the mesh will give me the mesh from the last time I ran this function. So if any of my objects have changed I will get missing surfaces or surfaces of objects I deleted since, and my materials are applied wrongly as the indexing no longer matches. So basically if I run this twice without changing any of my objects in my world then I will end up with the correct object.

 

now render_manager_reload mesh between having saved the mesh and loading the mesh back in seems to do nothing.

 

As for changing to ObjectMeshDynamic, this does in fact get me the model correctly (in terms of its geometric shape and materials), but the physics on it is completely broken. If the physics issue is easy to fix I could go down this path but I fear that it won't be. Heres hoping that clearFile() function will do the trick.

Link to post

That's really strange. render_manager_reload mesh should have helped you by reloading resources from a disk. Can you make up a small sample to reproduce the issue with saving and re-saving ObjectMesh? engine.filesystem.clearFile() is not what you are looking for in any case.

 

ObjectMeshDynamic and physics also should be working fine together (though slower than simple ObjectMesh).

Link to post

http://dl.dropbox.co...h%20problem.zip

 

Here it is.

- Use F1 to toggle between standard player and player actor cameras to test physics. (you will see at first that the scaled objects in scene will make for the bobbing of the actor object which we want to remove by combining out to one unscaled mesh object)

 

-use F2 to collect all nodes in scene (that are not lights) and save them to one mesh, then diabling those nodes and leaving you with the combined result. F2 again deletes that combination and renables those nodes. If you then add or delete nodes to the scene (say dragon.node from the demo) and then try hitting F2 again you will not get the dragon in the combined mesh. Hit F2 to revert and F2 again and the dragon will appear like previously described. Hope you can find the source of my problem!

 

NB. you will have to load editor in console to add nodes to scene but then unload the editor to access the actor player view or the camera will stay forced into the editor view.

 

PS. sorry if the controls seem a bit clunky, was trying to write the test scene as fast as possible

 

 

<Edit>

I think I somehow managed to run the program previously without actually calling calling render_manager_reload meshas I now get a memory access exception C++ side shortly after calling this;

 

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

 

I therefore assume this console function is not instantaneous? If so what is the approach to keep the script hanging until the meshes are fully reloaded?

 

 

As for the sample above, commenting out "engine.console.run("render_manager_reload mesh");" at line 191 should make hitting F2 runnable but with the problem as described.

Link to post
  • 2 weeks later...

This issue's fixed - your sample works like a charm (there's even no need to call "render_manager_reload mesh").

Link to post

BTW, you you can use a simpler code to handle pressing of the button by using clear function:

if(engine.app.clearKeyState(APP_KEY_F2)) {
  // code
}

instead of the following code:

if(engine.app.getKeyState(APP_KEY_F2) == 1 && prevStateF2 == 0) {
   // code
}

prevStateF2 = engine.app.getKeyState(APP_KEY_F2);

Link to post
  • 4 weeks later...

Hey, Carl.

 

I've played with your test scene and it seems to work fine. Combined mesh sucessfully reloads, nothing strange happened.

 

Here is my use case:

1. Launch sample without editor

2. Press F1

3. Press F2 several times

4. Load editor

5. Move hidden nodes (not combined one)

6. Quit editor

7. Press F1

8. Press F2 several times

 

Combined mesh correctly update itself. No crashes detected.

I've tried both on current dev binarines and on beta SDK's binaries (Release Mar 30 2012 r8760).

 

Do you still expecting problems with render_manager_reload mesh?

Link to post

Hi Bob,

 

Perhaps I wasn't clear enough as I think you have missed the point of what I'm trying to do. It always worked fine while you only transform the current nodes in the scene, its when you add new mesh data that you begin to see the problem. For instance follow this

 

 

 

1. Launch sample with editor

 

2. Press F2 twice ONLY (this will create the combined mesh (statue, floor and tree) for the first time and then will remove it leaving you back with the individual nodes)

 

3. Add a node -> Import node -> chose demos\heaven\nodes\cannon.node (or any other simple mesh node)

 

4. Press F2 once. Notice how the cannon has disappeared. What you are looking at is the combined mesh but the cannon doesn't seem to be there.

 

5. Press F2 again to revert back to the non combined nodes (cannon reappears)

 

6. Press F2 one more time to combine again. ta-dah!... and the cannon is part of the combined mesh.

 

 

 

So, why is it that it works for the first time you hit F2 (and it will always work as collectedObjects.mesh has not been loaded by the engine), but on subsequent combines, it does it not work on new mesh data, unless you do it twice. Hence why I've been trying to use something like "render_manager_reload mesh" but so far unsuccessful.

Link to post

Hey Carl,

 

Thanks for clarifying this to me. I have a solution for you. ;)

 

The problem is that console commands runs _after_ script update, so your code will save and load the same mesh. You need 1 update delay between save and load calls. I've modified your code, so it should help you.

problem.zip

Link to post