Can't get External Mesh Loader to work in irrBMAX

BlitzMax Forums/BlitzMax Programming/Can't get External Mesh Loader to work in irrBMAX

TomToad(Posted 2005) [#1]
Ok, I can't seem to get things working. I must be overlooking something. Here's what I have so far. Obviously, the engine is not calling isALoadableFileExtension() nor createMesh().



gman(Posted 2005) [#2]
teaches me to go from memory :) my apologies. i misguided you on a few steps. my changes are denoted with "GG":




TomToad(Posted 2005) [#3]
Hee hee, I tried out what you had and still couldn't get it to work. But then I discovered that I didn't even have the bridge.b3d file in the right directory to begin with. Moved the file and now it works. :)
Now to figure out how to actually get the file contents into an actual mesh.

ETA. Opps, another problem. The program hangs when it gets here:
  file.read(String Ptr(Varptr ChunkHeader),8)

I must be passing the parameters wrong or something. Any ideas?


gman(Posted 2005) [#4]
i think there is some issues with the new GC and the way i was doing string reading. could just be that we are approaching terrain that just hasnt been really hit yet by anyone.

one cool thing about this is that you should be able to use BMAX streams to access the file instead if you wish. just use the T_irrIReadFile to get the filename and then open a BMAX stream for the reading. i will see if i can hash out the readfile stuff as soon as i can. i also have some updated techniques i learned with the 3Impact wrapper so i may just implement those.


DStastny(Posted 2005) [#5]
Hi sorry to butt in but the problem is your type

Type T_chunk_header
Field id:Byte[4] <------ this wont work
Field length:Long
End Type

You can do this though

Type T_chunk_header
Field id: Int ' this i 4 bytes
Field length:Long
End Type

or

Type T_chunk_header
Field id_1: Byte
Field id_2: Byte
Field id_3: Byte
Field id_4: Byte
Field length:Long
End Type

Hope that helps...

Hi Gman :)

Doug Stastny


TomToad(Posted 2005) [#6]
Thanks Budman, but actually I just figured that one out a few minutes ago on my own :-)
So I replaced it with Int but it still doesn't work. The function that gman supplied expects a string ptr type. So how would I pass my type so that the function will see it as an 8 byte string instead of the T_chunk_header type?


DStastny(Posted 2005) [#7]
I assume you mean this function call?
If TestByteStringArray(ChunkHeader.id,"BB3D")
   Print "BB3D header found"
  Else
   Print "BB3D header not found"
  End If


Change it to this
If TestByteStringArray(varptr ChunkHeader,"BB3D")
   Print "BB3D header found"
  Else
   Print "BB3D header not found"
  End If


By taking the varptr of the type it returns a byte ptr to the first field. So you will get effectivly a ptr to 8 byte array.

I dont have Irrlicht installed with 1.12 at the moment so I cant compile what you have.

Doug Stastny


TomToad(Posted 2005) [#8]
Actually I was refering to this line
file.read(String Ptr(Varptr ChunkHeader),8)

That's where the program would hang. I've tried all different ways such as Varptr ChunkHeader.id, but it still wants to hang. I'm getting a feeling that the problem is with wrapper itself. Anyway, I temporarily fixed the problem by using BMax streams instead. Would rather use IrrLicht since the engine already has opened a stream, but until I can figure out what's going on, that's the best I can do.

GMan: when a mesh fails to load, what should createMesh return? I tried returning Null, false, 0, T_irrIAnimatedMesh(0), etc... but everything gives me errors.


DStastny(Posted 2005) [#9]
Tom,

I see it now. The BMX irrlicht wrapper is incorrect translation. I never used the IO classes, but reviewing the last version i have... I really need to get newer version.

Method read:Int(out:String Ptr,sizeToRead:Int)
		Local outBuffer:Byte[sizeToRead]
		Local retval:Int=0
		retval=IrrIO_IReadFile_read(handle,Varptr(outBuffer),sizeToRead)
		Local temp:String=String.FromBytes(outBuffer,retval)
		out=Varptr(temp)
		Return retval
	EndMethod


Wont work.

GMAN I have a little time to play this weekend you want me to review/fix the IO Classes?

Doug Stastny


TomToad(Posted 2005) [#10]
Ok, there seems to be very little documentation on this. The way I figure it, in order to create a simple mesh, you need to create an instance of T_irrSMeshBuffer. Use T_irrSMeshBuffer.getVertices() to get a pointer to the vertex buffer and add your vertices there. Then use T_irrSMeshBuffer.getIndices() to find the pointer of where you'll add the indices to.
set T-irrSMeshBuffer.Material to the material of the mesh and finally call T_irrSMeshBuffer.RecalculateBoundingBox() to set the bounding box of the mesh.

Am I right so far or am I way off? Then I'd need to create an instance of T_irrSMesh and use T_irrSMesh.AddMeshBuffer() to add the previously created mesh.
Then create an instance of T_irrSAnimatedMesh and use T_irrSAnimatedMesh.addMesh() to add the earlier created mesh. Then return the instance of T_irrSAnimatedMesh.

Do I have this right or am I completely off on this one?


Azathoth(Posted 2005) [#11]
file.read(String Ptr(Varptr ChunkHeader),8)

Blitzmax types aren't like c structs, you just can't get a pointer and fill it like you would a struct. A better way would be using a Bank or MemAlloc.


TomToad(Posted 2005) [#12]
Ok, I'm getting closer. The program I have down here will attempt to open a b3d file called bridge.b3d, but in reality, it's set up to just make a cube, just for testing purposes. I did manage to get something to show on the screen, but not exactly what I expected. Just point the bridge.b3d to point to your own b3d file. Contents don't matter, you can even haev a .txt file renamed to .b3d since I don't have it reading from it yet anyway.



gman(Posted 2005) [#13]
very nice so far TomToad :) Budman is graciously reworking the IO read functionality to get it to work. as for the disappearing box sides. im no expert, but it almost seems that you need to adjust the normals since we can see the inside of the box and then that side disappears when it rolls around.


DStastny(Posted 2005) [#14]
I sent fixes to gman so he can integrate an update to the irrlicht mod distro. I also sent him your posted code recoded to read from the IFile reader interface.

Should work well for you now. No you have the hard part parse the B3D file :)

If you want the changes before GMAN can get afixes up and can compile the mod shoot me an email @ doug_s@... and I will email the files to you that changed.

Doug Stastny


TomToad(Posted 2005) [#15]
Ok, looks like the box sides disappeared because I was indexing the vertices in the wrong order. I think I got one wrong and it just put all the rest out of whack. But there's still a problem though. Now I get a solid object, but it's nothing like a cube. :)


I had an idea while at work, There's a function called ISceneManager->addTestSceneNode() which creates a cube. I'll have a look in the irrLicht source and see if I can figure out what it's doing so I can get a better idea of how the meshes are created.


TomToad(Posted 2005) [#16]
After some experimenting, I'm finding that Vertex 0 is moving from 1,1,-1 to 0,1,-1. You can even see it shift about 1/2 second after the program starts.


TomToad(Posted 2005) [#17]
Ok, this is what I have so far. It's getting very close. Only problem is that it seems that the first element of the first vertex (X pos) changes to 0 about half a second after the program begins running. I don't know why. Possibly a bug in the wrappers? Or am I still missing something?



DStastny(Posted 2005) [#18]
That is strange bug. I took a look at it tonight can say I see why the mesh is being changed.

Ill try writing it in C++ without the wrapper.

Doug Stastny


TomToad(Posted 2005) [#19]
I had the same idea. Then I could know if the problem is with my logic or possibly a bug in the wrappers.

ETA:
This is weird. I decided to pare down the code to just the mesh creation before converting to c++ and this version actually works as expected. So there must be something wrong with either my implementation of the mesh loader functions, or there's a bug in the mesh loader wrappers.



DStastny(Posted 2005) [#20]
Interesting...

I dont think the problem is with the loader class. I have been playing with the manual control of GC and definitly something is gettting freed incorrectly. Hope you dont mind my helping I always love a good bug hunt.

Doug Stastny


DStastny(Posted 2005) [#21]
Here is the fix.

The vertexbuffer was getting garbage collected. GMAN had the comment forgot to pass FALSE

This should get it going :)

smeshbuffer.bmx
' ------------------------------------------------------------------------------------
'  irr::scene::SMeshBuffer wrappers (parent is IMeshBuffer)
' ------------------------------------------------------------------------------------
Public

Type T_irrSMeshBuffer Extends T_irrIMeshBuffer Final

	Function create:T_irrSMeshBuffer()
		Return createFromHandle(IrrScene_SMeshBuffer_new(),True)
	EndFunction

	Function createFromHandle:T_irrSMeshBuffer(pHandle:Int,bMustDel:Int=False)
		Local oRetVal:T_irrSMeshBuffer=New T_irrSMeshBuffer
		oRetVal.attach(pHandle,bMustDel)
		Return oRetVal
	EndFunction
		
	Method getBoundingBox:T_irrAABbox3df()
		'  do Not Delete this pointer
		Return T_irrAABbox3df.createFromHandle(IrrScene_SMeshBuffer_getBoundingBox(handle),False)
	EndMethod
	
	Method getIndexCount:Int()
		Return IrrScene_SMeshBuffer_getIndexCount(handle)
	EndMethod
	
	Method getIndices:T_irrArray_u16()
		'  do not delete this pointer
		Return T_irrArray_u16.createFromHandle(IrrScene_SMeshBuffer_getIndices(handle),False)
	EndMethod
	
	Method getMaterial:T_irrSMaterial()
		'  do Not Delete this pointer
		Return T_irrSMaterial.createFromHandle(IrrScene_SMeshBuffer_getMaterial(handle),False)
	EndMethod
	
	Method getVertexCount:Int()
		Return IrrScene_SMeshBuffer_getVertexCount(handle)
	EndMethod
	
	Method getVertexType:Int()
		Return IrrScene_SMeshBuffer_getVertexType(handle)
	EndMethod
	
	Method getVertices:T_irrArray_S3DVertex()
		'  do not delete this pointer
		' Return T_irrArray_S3DVertex.createFromHandle(IrrScene_SMeshBuffer_getVertices(handle))
		' dbs changed should have passed false
		Return T_irrArray_S3DVertex.createFromHandle(IrrScene_SMeshBuffer_getVertices(handle),False)
	EndMethod

	Method recalculateBoundingBox()
		IrrScene_SMeshBuffer_recalculateBoundingBox(handle)
	EndMethod

EndType






TomToad(Posted 2005) [#22]
Success! Thanks for the work Budman :)
Now I can get onto the next phase. Actually writing the B3D parser.


DStastny(Posted 2005) [#23]
I still think there is a couple of lurking issues. But I have to get with GMAN before I look at changing the code. Not sure I remember his intent in the wrappers.

Good luck cant wait to see it.

Doug Stastny


TomToad(Posted 2005) [#24]
Ok, now that I'm actually getting somewhere on this project, I decided to start a worklog.
http://www.blitzbasic.com/logs/userlog.php?user=7529&log=589


gman(Posted 2005) [#25]
good job TT :) a big thank you to Budman for tracking down the issues. a new release with the fixes is available in the worklog.


gman(Posted 2005) [#26]
k. ive been chatting with Budman and i see the issue he alluded too in his last post. in the createMesh() method, you need to be sure to call the grab() method on the instance of T_irrSAnimatedMesh before you return. this will properly sync the instance counting between Irrlicht and BlitzMax and avoid a rather potentially nasty crash.