Loading a Mesh From Any Path...VB.NET

arcanine

04-01-2012 21:43:52

Hello,

I'm about a month into learning how to use MOGRE. I've completed the basic tutorials and have begun experimenting. I found an old tutorial on embedding MOGRE in a Windows Forms application, which is what I've done. No problems there. The issue I'm having is I'd like to be able to load a mesh from a file path that the user selects. For example, the user might click a "Load Mesh" button, be presented with a standard Windows open file dialog, and select the mesh they wish to load. After clicking the dialog's "OK" button, I need to load the mesh.

I found the following code snippet here, but it's meant for OGRE and is therefore written in C++. I don't really know C++, so I haven't been able to convert the code into VB.NET for MOGRE.

I guess my biggest problem is how to fill the MemoryDataStream with the bytes from the file. As noted in the code that I have so far, VB.NET doesn't have an fread function, so I don't know how to actually get the bytes into memory.

For my code, the open file dialog is shown when the user clicks a LinkLabel control. The code for loading a mesh is wrapped in a function that returns true or false, which makes updating Form related things a lot easier.

I apologize for rendering of the code, I can't seem to get it to format in anything other than "cpp". I tried "VB.NET", "vbn", and "vb". "VB.NET" didn't work at all, while the others defaulted back to "cpp".

Private Sub lnkFile_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles lnkFile.Click
Using f As New OpenFileDialog
f.Filter = "Mesh Files (*.mesh)|*.mesh"
f.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
f.Multiselect = False
If f.ShowDialog = Windows.Forms.DialogResult.OK Then
If LoadMesh(f.FileName) Then
With lnkFile
.Text = f.FileName
.Font = New System.Drawing.Font(.Font, FontStyle.Regular)
End With
End If
End If
End Using
End Sub

Private Function LoadMesh(ByVal path As String) As Boolean
Try
' The following line is used to get the length of the file and allows for some other useful methods,
' like FileStream.Name
Dim fs As New System.IO.FileStream(path, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.None)

Dim memstream As New MemoryDataStream(path, fs.Length)
' Note: The MOGRE MemoryDataStream does not have an overloaded constructor method for
' "freeOnClose" or "readOnly". So we need to have the following line:
memstream.SetFreeOnClose(True)

' Here the C++ code calls the "fread" function. VB.NET does not have an fread function.
' I'm assuming this is how the MemoryDataStream gets filled with the bytes from the source file.
' This is where I get stuck. I don't know how to fill the MemoryDataStream

Dim pMesh As MeshPtr = MeshManager.Singleton.CreateManual(fs.Name, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME)

Dim meshSerial As New MeshSerializer
Dim stream As New DataStreamPtr(memstream)
meshSerial.ImportMesh(stream, pMesh)

' this is where I add the mesh to the scene.
Dim e As Entity = mScMan.CreateEntity(String.Format("{0}Ent", fs.Name), fs.Name)
Dim n As SceneNode = mScMan.RootSceneNode.CreateChildSceneNode(String.Format("{0}Node", fs.Name))
n.Position = Vector3.ZERO
n.AttachObject(e)

' make sure to return true to update form related stuff
Return True
Catch ex As Exception
' debugging purpose only...use a better/different message later.
MessageBox.Show(ex.ToString)

' make sure to return false to prevent updating of form related stuff
Return False
End Try
End Function

smiley80

04-01-2012 22:12:08

You can wrap managed stream with the 'ManagedDataStream' class:
var mesh = MeshManager.Singleton.CreateManual(meshName, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME);
using (var fileStream = File.OpenRead(pathToMesh))
{
using (var mds = new ManagedDataStream(fileStream))
{
MeshSerializer ms = new MeshSerializer();
using (var ds = new DataStreamPtr(mds))
{
ms.ImportMesh(ds, mesh);
}
}
}

Auto-converted to VB:
Dim mesh = MeshManager.Singleton.CreateManual(meshName, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME)
Using fileStream = File.OpenRead(pathToMesh)
Using mds = New ManagedDataStream(fileStream)
Dim ms As New MeshSerializer()
Using ds = New DataStreamPtr(mds)
ms.ImportMesh(ds, mesh)
End Using
End Using
End Using

arcanine

05-01-2012 03:22:38

Excellent! Thanks!

Tubulii

06-01-2012 09:36:24

Another possibility is to add the folder path to the resource manager and than load the mesh as usual. Any textures in this folder would automatically loaded (...). If you use for each mesh a separated resource group you could load and unload all allocated data very easily. For me it worked perfect...

arcanine

06-01-2012 16:03:05

Another possibility is to add the folder path to the resource manager and than load the mesh as usual. Any textures in this folder would automatically loaded...

In my case this would not be ideal, as I'm running OGRE in a Windows Forms application and needed the flexibility of a standard open file dialog. Nevertheless, (as you pointed out) there are certainly situations where this would work perfectly.

Pyritie

06-01-2012 16:58:08

Another possibility is to add the folder path to the resource manager and than load the mesh as usual. Any textures in this folder would automatically loaded...

In my case this would not be ideal, as I'm running OGRE in a Windows Forms application and needed the flexibility of a standard open file dialog. Nevertheless, (as you pointed out) there are certainly situations where this would work perfectly.

Yeah but doesn't the file dialog only return a filepath? You could extract the folder path from that and add it to the resource manager, then load the mesh as normal. I don't really see why you have to read the data from the file yourself.

Tubulii

06-01-2012 18:18:38

Another possibility is to add the folder path to the resource manager and than load the mesh as usual. Any textures in this folder would automatically loaded...

In my case this would not be ideal, as I'm running OGRE in a Windows Forms application and needed the flexibility of a standard open file dialog. Nevertheless, (as you pointed out) there are certainly situations where this would work perfectly.

Yeah but doesn't the file dialog only return a filepath? You could extract the folder path from that and add it to the resource manager, then load the mesh as normal. I don't really see why you have to read the data from the file yourself.


Yep, you are correct. Simple extract the folderpath (IO.Path.GetFullPath(YOUR_PATH)) and there you go.