miniB3D: monkey 3D engine - part8

Monkey Programming Forums/User Modules/miniB3D: monkey 3D engine - part8

AdamRedwoods(Posted 2013) [#1]


minib3d+monkey
Latest update v0.42.3

Download:
https://github.com/adamredwoods/minib3d-monkey
Wiki:
https://github.com/adamredwoods/minib3d-monkey/wiki

Win8 target:
https://github.com/sascha-schmidt217/minib3d-monkey

Thread continued from:
http://monkeycoder.co.nz/Community/posts.php?topic=5703




notes:
- current branch: v0.42.3 requires Monkey V70+
- tested on glfw, android, macos, ios, xna, webgl, flash

FEATURES:
- normals, textures, mipmaps, vertex buffers
- sprites and batch sprites
- context handling for mobile devices
- collisions and object/triangle picking
- animation: bone & vertex
- animated textures
- Load B3D (bin or base64), OBJ, MDD, PC2
- XNA, Win8, WinRT targets (courtesy of Rone)
- Shaders, extendable shaders
- normal mapping (opengl2.0)
- mojo 2D integration
- Ouya target compatibility

To Do:
- collada
- bones to quat/matrix internals
- vector class to use src,dst (minimize GC)
- fix win8
- glow shaders, shadows
- physics
- terrain
- octree scene manager
- mobile neon optimizations






AdamRedwoods(Posted 2013) [#2]
****************************************
minib3d v0.42

- context loss recovery for mobile: TShader.ResetShader(), TShader.FreeShader()
- bug fix with AlignToVector()
- TTexture.FreeTextureMemory() -- frees pixmap memory after binding
- TTexture pixmap reference counting for TTexture.FreeTexture()
- TPixmap.Free() -- mostly internal use
- Mipmapping on textures: now turned on (doh!)
- Added Sammy's TBatchSprite(texture,flags,batch_id) for existing textures
- EntityFX FXFLAG_PERPIXEL_LIGHTING. Only used in OpenGLES20 (so far). needed for Normal mapped textures.
- fixed a strange shader bug with Intel HD
- fixed sphere-sphere collision normal error
- vbo/shader last_state update errors
- Added Sammy's lightweight vertex animation handler. now consumes less memory. had to move anim_surf_frames to mesh instead of the anim_surface.
- collision setup defaults create tight EntityRadius sphere, based on mesh
- even more collision optimizations
- Added GetCulled:Bool() for testing if the mesh is seen by the camera (true).

v0.42.2
- MoveEntity() and TranslateEntity() behavior changed, consistent to blitz3d

v0.42.3
- fixed B3D stray vertex on some loads

OTHER THOUGHTS:
collisions (>200 entities) still seem quite slow on mobile, so i'll be looking into octree soon. that and i really want to get my collada importer done.


Sammy(Posted 2013) [#3]
Great stuff Adam! :D

There's a lot of optimisation and eye-candy added to this version, I really appreciate all the hard work you have put in on this release!

Many thanks,


blabz(Posted 2013) [#4]
Great work Adam!

Any way someone might be able to help\contribute?


AdamRedwoods(Posted 2013) [#5]
Any way someone might be able to help\contribute?

Lots of ways!
- The biggest way to help is to use it. Examples help finds bugs and bottlenecks. Games done in minib3d help promote it.
- documentation/tutorials. i'd like to get monkeydocs working with this and to get an automated program that creates it from the code. Midimaster stated some tutorials, and really helped me test out functionality.
- help port CannonJS. right now, i'm just figuring out what the different values are, since Javascript is not static typed, so type values are a darn mystery. once i get that done, i can use help to port code.
- test winrt and winphone8 on devices. i don't have these devices, so i can't test it. that said, i still need to update the win8 target with the current changes, so this is on hold for now.
- help write TTerrain function. i haven't touched this yet. may need a perlin noise texture gen to help test.

...and i'm open to ideas.


Sammy(Posted 2013) [#6]
Finally managed to grab some time and start testing the new version.

I get this error on my compile console output:

format_codebox('C:\Coding Folder\Middleware\Monkey Pro\bin\transcc_winnt.exe -run -config=debug -target=Html5_Game "C:\Coding Folder\Projects\MONKEY\Dungeon\Dungeon.monkey"
TRANS monkey compiler V1.56
Parsing...
miniB3D OpenglES20
Semanting...
C:/Coding Folder/Middleware/Monkey Pro/modules/minib3d/tsprite.monkey<511> : Error : Overriding method does not match any overridden method.
Abnormal program termination. Exit code: -1
ATTENTION: Compilation error reported by Trans: Overriding method does not match any overridden method.
')
Which points to this method:
format_code(' Method EntityFX(fx%)
mainsprite[batch_id].EntityFX(fx)
End')

Edit:

I got temporarily around this problem by changing "EntityFX(fx%)" to "EntityFX:TEntity(fx%)"

Also I'm loosing about 15% of my frame-rate by installing this update unfortunately, when compared to the previous update that is. So something new may be hogging the resources a little?


impixi(Posted 2013) [#7]

- help write TTerrain function. i haven't touched this yet. may need a perlin noise texture gen to help test.



For perlin/heightmap generation, there's code in the archives someone could butcher:

http://www.monkeycoder.co.nz/Community/posts.php?topic=1762#36624
http://www.monkeycoder.co.nz/Community/posts.php?topic=873#7205
http://www.monkeycoder.co.nz/Community/posts.php?topic=5730#65131

I'm on a 64bit linux platform at the moment, so my Monkey coding is suspended due to various issues, otherwise I'd attempt a basic TTerrain class...


Sammy(Posted 2013) [#8]
Also Angros's own CPP conversion of iminiB3D is over here...

http://sourceforge.net/projects/minib3d/files/

This has a TTerrain class (and a few other nice features like DirectX import for example).


AdamRedwoods(Posted 2013) [#9]
I got temporarily around this problem by changing "EntityFX(fx%)" to "EntityFX:TEntity(fx%)"


thanks, fixed & updated.

Also I'm loosing about 15% of my frame-rate by installing this update unfortunately, when compared to the previous update that is. So something new may be hogging the resources a little?

if the normalmap is working, then it's the normalmap. but if everything is the same, then i'll have to profile, or wait until i get octrees in.

For perlin/heightmap generation, there's code in the archives someone could butcher:

nice, i just may.
This has a TTerrain class (and a few other nice features like DirectX import for example).


yes, he's done some great work, i may have to look at it and ask permission.


Sammy(Posted 2013) [#10]
I meant to mention Angros's terrain class also has a nice efficient ROAM feature too.

if the normalmap is working, then it's the normalmap. but if everything is the same, then I'll have to profile, or wait until i get octrees in.


The normal mapping was already disabled because of the previous versions problems. Not sure how to help locate the bottleneck Adam, I do make extensive use of copyentity and copymesh. These commands are the basic building blocks of my level structure and I know you did some work on them. Can't be sure though if that's the problem though.


AdamRedwoods(Posted 2013) [#11]
the quick'n inaccurate way to profile code is to use html5 and use the browser's profiler. on chrome it's ctrl-shift-j, select profiles, click start.


Sammy(Posted 2013) [#12]
Thanks for the tip Adam, I'll try it tonight.


Sledge(Posted 2013) [#13]
Stuck my head in for a quick look at how things are going -- looks great! I don't think loading binary model files (woohoo!) was in the last time I gave it a pop but now it's there I have to hit you with a feature request: Any chance we can have a flag for flipping all the textures in a model? Maplet (yes Maplet, what?!) exports b3ds with all the textures upside down!

Great stuff, this -- makes me want to work on an idea I was throwing around a while back :D


Sammy(Posted 2013) [#14]
I spent some time with the Chrome profiler and came up with these comparison tables. I hope this helps.

BTW, I can send you the full CPU profiles if needed too Adam.

format_code('MiniB3D 0.41

Self Total Source Function
----------------------------------------------------------------------
74.97% 74.97% (idle)
5.32% 15.12% main.js:3564 c_OpenglES20.p_Render
1.76% 1.76% main.js:13668 c_TCamera.p_EntityInFrustum
1.50% 1.50% drawElements
1.46% 1.46% (program)
1.34% 17.81% main.js:3315 c_TRender.p_RenderCamera
1.10% 1.10% bindBuffer
0.98% 1.68% main.js:4435 c_MojoEmulationDevice.p_AddQuad
0.89% 0.89% uniformMatrix4fv
0.85% 0.85% (garbage collector)
0.84% 0.84% uniform1f
0.83% 0.83% uniform4fv
0.79% 1.68% main.js:2186 _glUniformMatrix4fv
0.65% 0.65% main.js:10819 c_VertexDataBuffer.p_PokeFloatArray
0.63% 0.63% vertexAttribPointer
0.54% 0.54% texParameteri
0.51% 0.51% uniform2f
0.36% 0.36% enableVertexAttribArray
0.35% 0.69% main.js:3197 c_TRender.m_UpdateWorld
0.33% 1.16% main.js:2150 _glUniform4fv
0.23% 0.23% main.js:5425 c_TEntity.p_Hidden
0.22% 0.22% uniform2fv
0.21% 0.21% bufferData
0.20% 0.20% main.js:19142 c_EffectState.p_Overwrite4
0.18% 1.74% main.js:18702 bb_graphics_DrawRect


MiniB3D 0.42

Self Total Source Function
----------------------------------------------------------------------
63.60% 63.60% (idle)
5.99% 24.99% :52309/main.js:3328 c_TRender.p_RenderCamera
5.26% 15.27% :52309/main.js:3581 c_OpenglES20.p_Render
3.20% 4.22% :52309/main.js:13777 c_TCamera.p_EntityInFrustum
2.22% 2.30% :52309/main.js:4624 c_QuadCache.p_AddCache
1.70% 1.70% drawElements
1.60% 3.89% :52309/main.js:4452 c_MojoEmulationDevice.p_AddQuad
1.46% 1.46% (program)
1.42% 1.42% bindBuffer
1.20% 1.20% (garbage collector)
0.89% 0.89% uniformMatrix4fv
0.82% 0.82% uniform1f
0.81% 0.81% uniform4fv
0.65% 0.65% :52309/main.js:6478 c_Matrix.p_TransformPoint
0.61% 0.61% vertexAttribPointer
0.61% 0.61% :52309/main.js:12644 c_Enumerator5.p_HasNext
0.52% 1.40% :52309/main.js:2186 _glUniformMatrix4fv
0.46% 0.46% uniform2f
0.45% 0.45% enableVertexAttribArray
0.41% 1.52% :52309/main.js:18804 bb_functions_UpdateWorld
0.30% 1.11% :52309/main.js:2150 _glUniform4fv
0.28% 27.36% :52309/main.js:3432 c_TRender.m_RenderWorld
0.28% 0.28% :52309/main.js:19334 c_EffectState.p_Overwrite4
0.26% 0.26% bufferData
0.23% 1.99% :52309/main.js:3392 c_TRender.m_RenderDrawList
')


AdamRedwoods(Posted 2013) [#15]
Any chance we can have a flag for flipping all the textures in a model?

texture.ScaleTexture(1.0,-1.0)
or
sprite.ScaleSprite(1.0,-1.0)
should do it, although i must admit i never tried it.

I spent some time with the Chrome profiler and came up with these comparison tables. I hope this helps.

looks like my QuadCache for MojoEmulation is acting up, but nothing really changed in the code. hmmm. try a third run and see if that still pops up. you can email me profile data if you want.


Sammy(Posted 2013) [#16]
EntityInFrustum seems to have jumped too, maybe this could explain why the Render functions have increased?

I'll post you the profiles just now Adam.


AdamRedwoods(Posted 2013) [#17]
EntityInFrustum seems to have jumped too, maybe this could explain why the Render functions have increased?

the percentage could go up because it is slower compared to everything else, so you'd have to look at number of execution times and time per execution.


Sledge(Posted 2013) [#18]
It was only a whimsical request, Maplet's output being somewhat canonical and texture orientation requiring engine-level management (you'd want textures automagically flipped but not flipped back should they be shared by, say, two .b3ds). Batch-flipping them as part of the art process works fine :D


Sammy(Posted 2013) [#19]
Mip-mapping seems to be working but I'm not having any joy with normal maps(still dark with no normal mapping) on animated meshes on Windows and Android I am afraid. HTML5 works wonderfully though with no issues and looks great.


EdzUp(Posted 2013) [#20]
Is there a way to stop sprites etc from not being rendered when they o off the side of the screen?

ATM my suns vanish when they go off the sides which don't happen in max's minib3d, anyone have any ideas.


Sledge(Posted 2013) [#21]
Maybe MeshCullBox if it has been implemented? Can't check ATM.


AdamRedwoods(Posted 2013) [#22]
Is there a way to stop sprites etc from not being rendered when they o off the side of the screen?

sledge's answer.
is it turning off before the frustum edge?


Sammy(Posted 2013) [#23]
I've added a little optimisation to TCamera that ads a pre-check for a bounding box camera range to bounding box entity into EntityInFrustum(). It seemed that I was loosing a lot of CPU time doing full frustum testing for entities that were no where near the frustum, esp. if it was a mesh which added further matrix mults to an already mult heavy plane frustum checking calculation(Downcasting Entity to TMesh is slow on HTML5 too). So I added this little sub as a helper. It works best in big environments with lots(I have over 400 in mine) entities spread across it. My camera range cover 5% at most at any one time, which I think is pretty typical. Now only a few addition and subs decides whether a full frustum check is needed for most of the off camera range entities.

Change this line...

Local mRadius:Float = Abs(ent.cull_radius)
to
Local mRadius:Float = Abs(ent.cull_radius)-20

To see it do clipping just within your camera range.

The code changes...

format_codebox(' 'Summary: Frustum cull pre-check using bounded box entity and a bounded box 360 degree camera range
Method InCamBB:Bool(ent:TEntity)
Local mRadius:Float = Abs(ent.cull_radius)
' If ent.classname = "Mesh" Then mRadius = Abs(mRadius * Max(Max(ent.gsx, ent.gsy), ent.gsz))
mRadius += Self.range_far
If Self.X > ent.X + mRadius or Self.X < ent.X - mRadius Then Return False
If Self.Y > ent.Y + mRadius or Self.Y < ent.Y - mRadius Then Return False
If Self.Z > ent.Z + mRadius or Self.Z < ent.Z - mRadius Then Return False
Return True
End

Method EntityInFrustum:Float(ent:TEntity)

If Not (InCamBB(ent)) Return 0

Local x#=ent.EntityX(True)
Local y#=ent.EntityY(True)
Local z#=ent.EntityZ(True)

Local radius#=Abs(ent.cull_radius) ' use absolute value as cull_radius will be negative value if set by MeshCullRadius (manual cull)

' if entity is mesh, we need to use mesh centre for culling which may be different from entity position
Local mesh:TMesh = TMesh(ent)
If mesh

'' transform mesh centre into world space
Local r:Float[] = ent.mat.TransformPoint(mesh.center_x,mesh.center_y,mesh.center_z)
x=r[0]; y=r[1]; z=r[2]

'' radius - apply entity scale

Local gs:Float = Max(Max(ent.gsx,ent.gsy),ent.gsz)
radius = radius*gs
If radius<0.0 Then radius=-radius

Endif

' is sphere in frustum

Local d#


d = frustum[0][0] * x + frustum[0][1] * y + frustum[0][2] * z + frustum[0][3] ''-z opengl
If d <= -radius Then Return 0
d = frustum[1][0] * x + frustum[1][1] * y + frustum[1][2] * z + frustum[1][3]
If d <= -radius Then Return 0
d = frustum[2][0] * x + frustum[2][1] * y + frustum[2][2] * z + frustum[2][3]
If d <= -radius Then Return 0
d = frustum[3][0] * x + frustum[3][1] * y + frustum[3][2] * z + frustum[3][3]
If d <= -radius Then Return 0
d = frustum[4][0] * x + frustum[4][1] * y + frustum[4][2] * z + frustum[4][3]
If d <= -radius Then Return 0
d = frustum[5][0] * x + frustum[5][1] * y + frustum[5][2] * z + frustum[5][3]
If d <= -radius Then Return 0


Return d + radius

End
')

Only lightly tested(I get 5-10% extra speed back BTW), so buyer beware! ;)


AdamRedwoods(Posted 2013) [#24]
I'm not having any joy with normal maps(still dark with no normal mapping)

ok i'll look into it.

I've added a little optimisation to TCamera that ads a pre-check for a bounding box camera range to bounding box entity into EntityInFrustum().

nice! i've been putting off on that optimization for an octree implementation.


Sammy(Posted 2013) [#25]
Thanks Adam.

A couple of extra notes/question.

There is no check to see if the Entity is hidden here, I don't see the need to frustum check for entities that are not going to be rendered, would adding one mess anything up?

The frustum check uses local mesh.center_x transformed to world coordinates. I've just stuck with the meshes global world coordinate field. Do you see this as a problem? It seems to work fine in the small tests I have done so far.

The remarked line is needed for scaled meshes but I was trying to avoid using down casting every entity to a TMesh, so I just tested the .classname for "Mesh". I was kind of surprised that there was not a better way to do this. I would have assumed that entities would have a "classtype:Int" for quick class separation. Maybe something add to TEntity in the future to avoid string comparisons/downcasting altogether?


AdamRedwoods(Posted 2013) [#26]
There is no check to see if the Entity is hidden here, I don't see the need to frustum check for entities that are not going to be rendered

TRender.RenderCamera() is the main render loop which includes Hidden() check.

I've just stuck with the meshes global world coordinate field. Do you see this as a problem?

should be fine. frustum uses world coords for the check.

Maybe something add to TEntity in the future to avoid string comparisons/downcasting altogether?

I did start to do this for TSprite a while back (TMesh.isSprite:bool) but for most platforms it made little difference. It's a programming style that I waiver between, but (for clarity sake and to rely on the compiler) I avoid those types of micro-optimizations for now. The exception, I do try to cache the downcast if I use it at least twice. So in that routine, mesh=TMesh(ent) you can move up the downcast to save some cycles perhaps.

When i get around to octree, it will cull out most objects with very little overhead.

Also keep in mind that HTML5 is VERY slow in debug mode because of glerror() checks (if you are testing HTML5).


Sammy(Posted 2013) [#27]
OK, thanks again Adam, that cleared up quite a few niggles I had. :)

Adding an octree should be great BTW, as it will exclude entities en-mass per node, a feature that should allow MB3D to use extremely large levels of entities!


EdzUp(Posted 2013) [#28]
Well at the moment the sprites that go one pixel off either edge of the screen vanish, I will play with MeshCullBox and see what happens :)


EdzUp(Posted 2013) [#29]
All I get is 'identifier "MeshCullBox" not found" so im guessing its not in there yet, on BlitzMax minib3d the sprites can go off the side and look perfect all I wanted is the same performance from monkey minib3d :)


AdamRedwoods(Posted 2013) [#30]
Well at the moment the sprites that go one pixel off either edge of the screen vanish

bug confirmed and fixed, thank for finding that! v0.42.1

TSprite.ScaleSprite() was not updating cull sphere.


EdzUp(Posted 2013) [#31]
ah brilliant glad to help :)

Edit: is there a total cross platform way to edit textures yet all i want to do is grab a 256x256 section of the screen and use it in game?


Sammy(Posted 2013) [#32]
Trying to pick-up shaders, so many things to learn! :P Adam, if you have some spare time, would it be possible to provide a quick and dirty, "hello world" demo for using shaders in MB3D?

Many thanks,


EdzUp(Posted 2013) [#33]
Righty when creating my Star Rogue game I was having major problems with MoveEntity, firstly when moving sprites they move perfectly but meshes moved WAAAY more than they should. As an example I move my planets between 650.0 to 12000.0 BUT the system moved them over 70000.0 which is wrong considering that the ranges were set.

To fix this on the planet system I created PlaceItem that just places ALL planets on the game with a simple Sin/Cos routine and now they are placed perfectly.

What I wanted to know is has anyone else had this problem with minib3d, all I do is simply position the entity at 0,0,0 and then move it to a range. Doing this yields different results for sprites and entities which is strange.


slenkar(Posted 2013) [#34]
are you scaling anything?
scaling an entity changes the distances it moves too
(in the original Blitz3D)


EdzUp(Posted 2013) [#35]
Yeah in scaling it but surely moving something 50.0 forwards should not be effected by its scale. Otherwise something like an asteroid field with different sized asteroids couldn't be done in minib3d.

blitzmax minib3d don't have this problem nor did blitz3d, even unity doesn't either.


Sammy(Posted 2013) [#36]
Have you tried removing the scaling commands temporarily to see if the problem persists?


EdzUp(Posted 2013) [#37]
Will do some tests as to be honest scaling shouldn't affect movement after all no matter what scale something is 50.0 is 50.0 when ya want to move it 50 it should move just that.


Sammy(Posted 2013) [#38]
I agree Ed. TBH I have not come across the problem that you have but I mainly use PositionEntity and TranslateEntity for asset positioning, although I've used MoveEntity, without problems too I think.


AdamRedwoods(Posted 2013) [#39]
re:MoveEntity

it's a fair point.

original blitz3d docs says:
http://www.blitzmax.com/b3ddocs/command.php?name=MoveEntity&ref=3d_cat
Moves an entity relative to its current position and orientation.

What this means is that an entity will move in whatever direction it is facing. So for example if you have an game character is upright when first loaded into Blitz3D and it remains upright (i.e. turns left or right only), then moving it by a z amount will always see it move forward or backward, moving it by a y amount will always see it move up or down, and moving it by an x amount will always see it strafe.



ok, so MoveEntity would be this
format_code('
**see github
')

Question: is MoveEntity scaled if it's parent is scaled?
i thought about this, and perhaps i'd need a "global flag" in the method parameters to remove the parent scaling. the other option is to always make this global.


EdzUp(Posted 2013) [#40]
Yeah as long as moving it forwards x amount isn't affected by scaling at all as no scaling should be used in the calculation, if we wanted scaling we can add it in.


AdamRedwoods(Posted 2013) [#41]
v0.42.2 updated
also found a TranslateEntity() problem with parenting.


Sammy(Posted 2013) [#42]
Not at my computer just now but I think MoveEntity with a Global/Local flag would be ideal as this fits in with the other positional methods. With the default keeping the current functionality for backwards compatibility. The main reason for scaling movement in this way, with the parent, would be for custom grouping and scaling of objects I would imagine.


AdamRedwoods(Posted 2013) [#43]
The MoveEntity description states that it moves in the direction the entity is facing, so therefore, it is always forced into a entity local coordinate system. although we could add a global flag, i think it would only apply to the scaling.

my thought is to keep it this way until someone shows a demonstration needing this functionality.


Sammy(Posted 2013) [#44]
Sounds fair to me.

BTW Adam, if I use per pixel lighting(and possibly normal maps) on Android my tablet now resets when I exit my game. This has been since .41, I apologise for reporting this a bit late as I disabled both features(and promptly forgot all about it) to enable me to debug the rest if the game while you were working on the normal mapping. Anyone else have this?

Also, I just discovered that I got a very nice 10% speed boost to my rendering using the new KitKat update and MB3D! :)


AdamRedwoods(Posted 2013) [#45]
BTW Adam, if I use per pixel lighting(and possibly normal maps) on Android my tablet now resets when I exit my game.

the whole tablet resets? thats a tough one, hard to debug, but probably driver or memory related.
are you reloading your shaders and textures in OnResume()? maybe try to see if one or the other is messing things up.


Sammy(Posted 2013) [#46]
Just un-remarked the offending lines, no crashing now?!?! I must have initiated the crash in some other way that I have since fixed unintentionally. Not my night! ;)


blabz(Posted 2013) [#47]
Disregard.


blabz(Posted 2013) [#48]
Does the XNA version contain all of the OpenGL version features?


AdamRedwoods(Posted 2013) [#49]
Does the XNA version contain all of the OpenGL version features?

XNA has two modes: profile(HD) and reach. reach is pretty limited, but works on WP7. that is the mode i have been maintaining in minib3d.

so no, XNA does not contain all the opengl features. only 1 texture, and only 1 distance light only.

the more robust XNA and Win8 stuff that Rone wrote is much more powerful. i am still working out odd bugs in migrating it into the base miniB3D. (plus, i have no Win tablets/phones to test it on, just Win8).


Rone(Posted 2013) [#50]
hey adam,

have you already started with the windows 8.1 adjustments and integration into latest minib3d?
I have currently some time to make it...


AdamRedwoods(Posted 2013) [#51]
i wonder if that's the memory exception i'm running into? VS2012 is giving me no debug info. running monkey v76.


Rone(Posted 2013) [#52]
In order to compile with the latest monkey version(v76d), I changed the following:

- replaced TARGET="win8" with TARGET="winrt"
- replaced Print with bbPrint
- replaced BBWin8Game with BBWinrtGame
- replaced ::Win8Game() with ::WinrtGame()
- replaced .ToCString<wchar_t> with .ToCString<char> in BBD3D11_INPUT_ELEMENT_DESC::Create

Then 'animation_test.monkey' compiled and started successfully...

Can you describe the exception in more detail?

Enable native code debugging:
MonkeyGame\Properties\Debug\Debugger type\Mixed

------------------------------------

I did describe here, how to load custom hlsl shaders https://github.com/sascha-schmidt217/minib3d-monkey/wiki/Release-Notes
Since win8.1 supports runtime shader compilation/reflection, this can be handled more user friendly now...


EdzUp(Posted 2013) [#53]
One question does minib3d allow for flight controls or is it a straight port of max minib3d fps system?


AdamRedwoods(Posted 2013) [#54]
One question does minib3d allow for flight controls or is it a straight port of max minib3d fps system?

?
you need to make your own controls.
you can make an entity move forward 0.2 units in the "local forward axis" direction with EntityMove(0,0,0.2).


EdzUp(Posted 2013) [#55]
Nah ya misunderstand, what i was talking about is if you roll 45 degrees left then pitch up does it pitch up in relation to the objects orientation like a plane OR like the original minib3d where it was as if the rotation was 0 so no matter what you had fps controls this was fixed by warner later on the bb.com forums :)


Sammy(Posted 2013) [#56]
Gimbal lock?


EdzUp(Posted 2013) [#57]
Nah quaternion rotation over Euler, is flight rotation over fps rotation system.


AdamRedwoods(Posted 2013) [#58]
Nah quaternion rotation over Euler, is flight rotation over fps rotation system.

Euler rotations, no quaternions. Quaternion is on my TODO but very low priority.
Everything internally is matrix based, so yes, you will get gimbal lock.
I've added the entity.AlignToVector(x,y,z, axis, slerp speed), which is internally quat->matrix based so that it can potentially get rid of the gimbal lock.


Sammy(Posted 2013) [#59]
entity.AlignToVector(x,y,z, axis, slerp speed)
Handy! :)


EdzUp(Posted 2013) [#60]
Handy indeed, i will try to do the same thing i did with the original and see what happens from the db classic days


Sammy(Posted 2013) [#61]
Fragmotion is 70% off($15) for the Christmas period, http://www.fragmosoft.com/

Why mention it here? I bought this at full price(and its well worth it at that price) and have found it to be an essential tool when using miniB3D. Messing with file conversions, internal paths, bones, texture formats etc... all the things you need to get your models in your Monkey+miniB3D game. I really could not do with out it when using miniB3D now.


bruZard(Posted 2014) [#62]
@Adam: Are you sure CollisionNX/NY/NZ are returning values like Blitz3D? I get really confusing values, unlike Blitz3D


AdamRedwoods(Posted 2014) [#63]
Are you sure CollisionNX/NY/NZ are returning values like Blitz3D? I get really confusing values, unlike Blitz3D

no, i rewrote most of the collision stuff, and i don't have the original b3d to test this stuff against. but the normals should be accurate and normalized.
...do i need to flip my NZ?


bruZard(Posted 2014) [#64]
i think CollisionN* should return a value between -1.0 and 1.0 ... that is it what B3D do...


AdamRedwoods(Posted 2014) [#65]
i think CollisionN* should return a value between -1.0 and 1.0 ... that is it what B3D do...

i must be missing a normalization somewhere. a quick glance-- i missed it on ray-triangle, so that would effect TPick. is that where the normal is wrong? what collision type is wrong?


bruZard(Posted 2014) [#66]
In B3D i can use CollisionN* to move my objects against the collided normal. With miniB3D this doesn't work


AdamRedwoods(Posted 2014) [#67]
try
format_code('
Local vecNorm:Vector = New Vector( obj.CollisionNX(), obj.CollisionNY(), obj.CollisionNZ() )
vecNorm = vecNorm.Normalize()
')
also see if flipping the sign "obj.CollisionNZ()" to "-obj.CollisionNZ()" works.

Also, setting the collision response to COLLISION_RESPONSE_SLIDE or COLLISION_RESPONSE_SLIDEXZ should slide objects against each other.

EDIT: fixed code above


bruZard(Posted 2014) [#68]
Vector::Normalize() doesn't work, after that the normals has the same values as before.

My setup:


In Update():
format_code('
Local v:Vector = New Vector(b.model.CollisionNX(), b.model.CollisionNY(), b.model.CollisionNZ())

Print "before: " + v.z
v = v.Normalise()
Print "after: " + v.z
')


bruZard(Posted 2014) [#69]
i think it's a bug ... i need the normals of the table, but i get just 0, 0, 0.


Sledge(Posted 2014) [#70]
Having a wee problem with a .b3d file exported from Maplet. Got an errant vert when loaded into MiniB3D!



Look at it -- all high and mighty up-in-the-air as it it were better than all the other verts :D Looks fine in Maplet and in Decorator (funnily enough if you load it into Decorator then save it back out it causes a completely different tri to look wrong in MiniB3D!)

B3d file and textures here: http://www.into-games.com/extra/temp/VertFail.zip


Hammer(Posted 2014) [#71]
Hi, thanks for your amazing work on creating this module for monkey.

I'm attempting to load my own bone animated b3d file but I keep running into roadblocks, When using Fragmotion as the exporter the model loads correctly but just doesn't animate. I searched the boards and saw someone else had a similar problem and supposedly there was a fix being implemented, has it not made the code yet? There was talk of a temp fix similar of "if weight=0.0 then weight=1.0" but I haven't the slightest clue where to start with this. I run into a completely different when using the b3d pipeline plugin for 3ds Max 9 the entire program stalls out and I get an "Monkey Runtime Error : Array index out of range" error. The animations plays fine in various b3d viewers so I don't think the problem is with the animation or exporters. Any suggestions on what I may be doing wrong or what I can do to fix my issues?


AdamRedwoods(Posted 2014) [#72]
When using Fragmotion as the exporter the model loads correctly but just doesn't animate.

if you can, send the model to me. i don't need the textures. awpiette at yahoo dot com.

i'll look into these other problems as well this week.


bruZard(Posted 2014) [#73]
why the table doesn't response collisions?
format_code('
Strict

Import minib3d.app
Import mojo

Class Game Extends MiniB3DApp
Field ball:TMesh, table:TMesh
Field cam:TCamera, light:TLight

Method Create:Int()
SetUpdateRate(30)
SetRender()

PreLoad("ball01.jpg")
PreLoad("mojo_font.png")

Return 0
End

Method Init:Int()
SetFont(LoadImage("mojo_font.png",96,Image.XPadding))

ball = LoadMesh("ball01.obj")
table = LoadMesh("table01.obj")
cam = CreateCamera()
light = CreateLight(2)

ball.EntityTexture(LoadTexture("ball01.jpg"))

cam.Position(0.0, 7.0, -2.0)
cam.Rotate(45.0, 0.0, 0.0)

light.Position(0.0, 5.0, 5.0)
light.LightRange(50)


ball.CollisionSetup(1, COLLISION_METHOD_BOX)
table.CollisionSetup(1, COLLISION_METHOD_POLYGON)
Collisions(1, 1, COLLISION_METHOD_POLYGON, COLLISION_RESPONSE_SLIDEXZ)

Return 0
End

Method Update:Int()
ball.TranslateEntity(0.2, 0.0, 0.2)

Local bc:Int = ball.CountCollisions()
Local tc:Int = table.CountCollisions()

If bc >= 1 Print "ball collisions: " + bc
If tc >= 1 Print "table collisions: " + tc

UpdateWorld()

Return 0
End

Method Render:Int()
RenderWorld()

Return 0
End
End

Function Main:Int()
New Game()
Return 0
End
')

files for this code: http://www.colorflow.de/monkey/downloads/data.zip


bruZard(Posted 2014) [#74]
omg ... i got it: the return value is just to big.

format_code('
Local collCount:Int = b.model.CountCollisions()
If collCount > 0
Local nx:Float = Float(String(b.model.CollisionNX())[..4])
Local nz:Float = Float(String(b.model.CollisionNZ())[..4])

If nx <> 0 b.dx = nx * 0.2
If nz <= 1 And nz >= -1 b.dz = nz * 0.2

b.model.TranslateEntity(b.dx, 0.0, b.dz)
')


bruZard(Posted 2014) [#75]
yet another miniB3D bug: the red marked area in the picture is the area i have to touch/click before i get picked coordinates from the rest of the screen




Hammer(Posted 2014) [#76]
I managed to get the model to animate, the problem was with the texture. I had multi-sub texture on a single mesh(multiple files), I just decided to merge my textures together for the time being no major biggie. Has LoadAnimSeq been implemented yet?


Deen(Posted 2014) [#77]
i'm having one weird issue... ive download experimental 77a + the latest miniB3D last week.. and start with a simple tutorial from the other post (for miniB3D + Monkey). it works like a charm until yesterday. turn off my PC and runaway, then turn on again just now and try to continue my tutorial, i'vet got and error message at Chrome print "**Shader Linking Error". my program at html 5 (using Chrome) actually running only that i can't see any mesh on the screen.. i found that 'Light' is the main issue here. it was like the scene has no light at all even i created it (this is still the first tutorial file im playing with - but yesterday everything works, even i try with changing the light to omni or spot, it works). When i et the mesh to full bright (so no light affected now) then i can see the mesh. i revert back the compiler to MonkeyProv69 + old miniB3D now also cant run the tutorial above without success (yesterday it is OK!)????

another thing is, ive tried with Monkey Pro v69 + old minib3d and it works on every examples file without any problem.. but when i try with experimental 77a + latest minib3D, i have zombie examples working without light i guess. all zombies looks shade in black.???

but every issue above, when i compile it for Desktop (glfw) it works just fine... is there any light issue before this (that cause shader linking error)?


AdamRedwoods(Posted 2014) [#78]
I managed to get the model to animate, the problem was with the texture. I had multi-sub texture on a single mesh(multiple files), I just decided to merge my textures together for the time being no major biggie. Has LoadAnimSeq been implemented yet?

cool, the number of textures depends on the shader. opengles1.1 allows 8, opengles2.0 current shader allows 4, xna allows 1.

LoadAnimSeq() code is in there, but i've never used it. if you let me know (verbosely) what it's SUPPOSE to do, i can get it running properly.

but when i try with experimental 77a + latest minib3D, i have zombie examples working without light i guess. all zombies looks shade in black.???

should work ok, but you never know. make sure to delete the old "zombie.build" folder to get rid of anything that may still be incompatible.
also make sure you're getting "..Full shader success" and "..FastBright shader success". i suspect full shader is not working for you, but fast bright is working, which is why when you disable lights you can see things again. also check to see if there's an error log in the beginning when the shaders are being compiled.

my other guess is chrome updated it's ANGLE driver when you turned it off, so that's why something is amiss when compiling (ANGLE is an opengl to directx JIT compiler).


Deen(Posted 2014) [#79]
Thanks Adam... aha! i reckon this is the one which rang me a bell.... https://chromium.googlesource.com/angle/angle... it is updated 3 days ago...


EdzUp(Posted 2014) [#80]
Now I know that minib3d has mojo emulation so we can render images onto the screen but is there emulation for using images loaded from a sheet like fonts etc?

I am loading a sheet of fonts with LoadImage( "font_16.PNG", 10, 16, 64 ) but when I render anything with this image I get nothing on screen, I have tested the same code using standard mojo and it works perfectly everytime.


Sammy(Posted 2014) [#81]
Have you preloaded the "font_16.PNG"?


EdzUp(Posted 2014) [#82]
Yeah its preloaded although Adam has said before that preloading is for html5 only and this is glfw.


AdamRedwoods(Posted 2014) [#83]
I am loading a sheet of fonts with LoadImage( "font_16.PNG", 10, 16, 64 ) but when I render anything with this image I get nothing on screen, I have tested the same code using standard mojo and it works perfectly everytime.

i just did a quick test with those settings and it seems ok.
Notes:
make sure that SetRender() is set BEFORE any LoadImages.
make sure that SetMojoEmulation() is set in the OnRender() method and BEFORE you use any mojo drawing commands.


EdzUp(Posted 2014) [#84]
Yeah it seems to fail here will look onto it and see what's going wrong


EdzUp(Posted 2014) [#85]
It seems that one of my scaling imports was corrupted I have replaced the file and it all works brilliantly now, thanks adam for ya help :D


AdamRedwoods(Posted 2014) [#86]
Having a wee problem with a .b3d file exported from Maplet. Got an errant vert when loaded into MiniB3D!

yes, BUG!
fixed v0.42.3 on github (bug was in monkeybuffer.monkey).


AdamRedwoods(Posted 2014) [#87]
re:collisions
i think it's a bug ... i need the normals of the table, but i get just 0, 0, 0.

your code:
format_code('Local nx:Float = Float(String(ball.CollisionNX())[..4])
Local nz:Float = Float(String(ball.CollisionNZ())[..4])')
is dangerous because when values become 9.999988000 e-15 then your string becomes 9.9999.

this code bounced the ball around just fine:
format_code('If ball.CountCollisions()>0
Local nx:Float = ball.CollisionNX()
Local nz:Float = ball.CollisionNZ()
Local dp# = bx*nx+bz*nz ''dot product
bx = bx-2*nx*dp ''ray reflection
bz = bz-2*nz*dp
Endif

ball.TranslateEntity(bx, 0.0, bz)')


Deen(Posted 2014) [#88]
we know that b3d files is already can be loaded in minib3d - monkey along with the bones animation, just wanna know how far the compatibility compare to the old b3d format? is that multitexturing still can be loaded. since im thinking to set all my models with full bright (entityfx = 1) beacuse i already have a few models (from old time blitz3d) with ambient occlusion / lightmap ready...


EdzUp(Posted 2014) [#89]
Also is there still a way to get bone positioning data for each model at all times and rotations :)


bruZard(Posted 2014) [#90]
thank you Adam!


Sledge(Posted 2014) [#91]
yes, BUG!
fixed v0.42.3 on github (bug was in monkeybuffer.monkey).

Ace! Downloading...


AdamRedwoods(Posted 2014) [#92]
is that multitexturing still can be loaded.

multitexturing works, but NOT in XNA (yet). also try to limit your multi textures to about 4. if you need more that 4 shaders in html5/opengl2.0, let me know i can expand the shader.

is there still a way to get bone positioning data for each model at all times and rotations

bones are entities, should work just like any other. let me know if it doesn't.
now, if you want to control bones using Position,Rotate, etc, you need to use entity.ActivateBones().


EdzUp(Posted 2014) [#93]
I was wondering if the commands were the same as blitz3ds :)


Landon(Posted 2014) [#94]
does multitexturing work in html5? I noticed that if my model had two textures on it only one surface of the model animates, but if i consolidate it into one texture the entire model animates. My target is OUYA but for quick testing i use html5.. i have to see if this still does the same thing on OUYA


Landon(Posted 2014) [#95]
hmm i'm gonna check my model seems like i get the same problem in GLFW, could be something on my end.


time-killer-games(Posted 2014) [#96]
I gotta say this is still the most useful and significant module for Monkey-X to date. =)


Landon(Posted 2014) [#97]

LoadAnimSeq() code is in there, but i've never used it. if you let me know (verbosely) what it's SUPPOSE to do, i can get it running properly.



I could really use LoadAnimSeq() as well, it basically allows you to load a b3d file and only grabs the animation data and appends the frame to an existing model and returns the track id.


Landon(Posted 2014) [#98]
Here is a very sloppy band-aid fix for LoadAnimSeq but it will show you how it works.

In Tmodelb3d.monkey

format_code('
Function LoadAnimSeq:Int(mesh:TMesh,f_name$)

Local data:DataBuffer = DataBuffer.Load(FixDataPath(f_name))

If DEBUGMODEL Then Print"..loading B3DBinary:"+FixDataPath(f_name)

If Not data Or (data And data.Length() <=1)
Print "**File not found: "+f_name
Return -1
Endif

Return ParseB3DAnim(mesh, data)

end

Function ParseB3DAnim:int(mesh:TMesh, data:DataBuffer, override_texflags:Int=-1)
' Header info

Local tag:Int
Local prev_tag:Int
Local new_tag:Int
Local vno:Int

Local file:BufferReader = BufferReader.Create(data)

''read BB3D

tag=file.ReadTag()

If DEBUGMODEL Then Print "TModel "+PrintTag(tag)

vno =file.ReadInt() 'tag
vno =file.ReadInt() 'size

vno =file.ReadInt() 'version

If tag<>BB3D Print "Invalid b3d file"; Return -1
If Int(vno*0.01) >0 Print "Invalid b3d file version"; Return -1

' Locals

Local size:Int
Local curSize:Int
Local node_level:Int=-1
Local old_node_level:Int=-1
Local node_pos:Int[100]

' tex local vars
Local tex_no:Int=0
Local tex:TTexture[1]
Local te_file$
Local te_flags:Int
Local te_blend:Int
Local te_coords:Int
Local te_u_pos#
Local te_v_pos#
Local te_u_scale#
Local te_v_scale#
Local te_angle#

' brush local vars
Local brush_no:Int
Local brush:TBrush[1]
Local b_no_texs:Int
Local b_name$
Local b_red#
Local b_green#
Local b_blue#
Local b_alpha#
Local b_shine#
Local b_blend:Int
Local b_fx:Int
Local b_tex_id:Int

' node local vars
Local n_name$=""
Local n_px#=0
Local n_py#=0
Local n_pz#=0
Local n_sx#=0
Local n_sy#=0
Local n_sz#=0
Local n_rx#=0
Local n_ry#=0
Local n_rz#=0
Local n_qw#=0
Local n_qx#=0
Local n_qy#=0
Local n_qz#=0

' mesh local vars
'Local mesh:TMesh
Local m_brush_id:Int

' verts local vars
Local v_mesh:TMesh
Local v_surf:TSurface
Local v_flags:Int
Local v_tc_sets:Int
Local v_tc_size:Int
Local v_sz
Local v_x#
Local v_y#
Local v_z#
Local v_nx#
Local v_ny#
Local v_nz#
Local v_r#
Local v_g#
Local v_b#
Local v_u#
Local v_v#
Local v_w#
Local v_a#
Local v_id

' tris local vars
Local surf:TSurface
Local tr_brush_id:Int
Local tr_sz:Int
Local tr_vid:Int
Local tr_vid0:Int
Local tr_vid1:Int
Local tr_vid2:Int
Local tr_x#
Local tr_y#
Local tr_z#
Local tr_nx#
Local tr_ny#
Local tr_nz#
Local tr_r#
Local tr_g#
Local tr_b#
Local tr_u#
Local tr_v#
Local tr_w#
Local tr_a#
Local tr_no:Int

Local vert_lookup:Int[]
Local vert_surf_lookup:Int[]

' anim local vars
Local a_flags:Int
Local a_frames:Int
Local a_fps:Int

' bone local vars
Local bo_bone:TBone
Local bo_no_bones:Int
Local bo_vert_id:Int
Local bo_vert_w#

' key local vars
Local k_flags:Int
Local k_frame:Int
Local k_px#
Local k_py#
Local k_pz#
Local k_sx#
Local k_sy#
Local k_sz#
Local k_qw#
Local k_qx#
Local k_qy#
Local k_qz#

Local parent_ent:TEntity=Null ' parent_ent - used to keep track of parent entitys within model, separate to parent_ent_ext paramater which is external to model
Local root_ent:TEntity=Null

Local last_ent:TEntity=Null ' last created entity, used for assigning parent ent in node code

Local totaltris:Int=0

' Begin chunk (tag) reading

Repeat

new_tag=file.ReadTag()

If NewTag(new_tag)=True

prev_tag=tag
tag=new_tag

file.ReadInt() 'tag
size=file.ReadInt() 'size
curSize=0

' deal with nested nodes

old_node_level=node_level
If tag=NODE ' "NODE"

node_level=node_level+1

If node_level>0

Local fd=0
Repeat
fd=file.Position()-node_pos[node_level-1]
If fd>=8

node_level=node_level-1

Endif

Until fd<8

Endif

node_pos[node_level]=file.Position()+size

Endif

' up level
If node_level>old_node_level

If node_level>0
parent_ent=last_ent
Else
parent_ent=Null
Endif

Endif

' down level
Local tent:TEntity
If node_level<old_node_level

tent=root_ent

' get parent entity of last entity of new node level
If node_level>1

Local cc
For Local levs=1 To node_level-2
cc=tent.CountChildren()
tent=tent.GetChild(cc)
Next
cc=tent.CountChildren()
tent=tent.GetChild(cc)
parent_ent=tent

Endif

If node_level=1 Then parent_ent=root_ent
If node_level=0 Then parent_ent=Null

Endif

' output debug tree
If DEBUGMODEL
Local tab$=""
Local info$=""
If tag=NODE And parent_ent<>Null
info=" (parent= "+parent_ent.name+")"
Else If tag=NODE And root_ent<>Null
info=" ("+root_ent.name+")"
Endif
For Local i=1 To node_level
tab=tab+"-"
Next
Print tab+" "+PrintTag(tag)+" "+info
Endif

Else

tag=0

Endif



Select tag

Case TEXS '"TEXS"

'Local tex_no=0 ' moved to top

new_tag=file.ReadTag()

While NewTag(new_tag)<>True And file.Eof()<>True

te_file=B3DReadString(file)

If te_file.Length <=1 Then Exit

te_flags=file.ReadInt()
te_blend=file.ReadInt()
te_u_pos=file.ReadFloat()
te_v_pos=file.ReadFloat()
te_u_scale=file.ReadFloat()
te_v_scale=file.ReadFloat()
te_angle=file.ReadFloat()

If te_flags&65536
te_flags=te_flags-65536
te_coords=1
Else
te_coords=0
Endif

If override_texflags >-1 Then te_flags = override_texflags

' convert tex angle from rad to deg
te_angle=te_angle*(180.0/PI)


new_tag=file.ReadTag()


Wend

Case BRUS

'Local brush_no=0 ' moved to top

b_no_texs=file.ReadInt()

new_tag=file.ReadTag()

While NewTag(new_tag)<>True And file.Eof()<>True

b_name=B3DReadString(file)
b_red=file.ReadFloat()
b_green=file.ReadFloat()
b_blue=file.ReadFloat()
b_alpha=file.ReadFloat()
b_shine=file.ReadFloat()
b_blend=file.ReadInt()
b_fx=file.ReadInt()

For Local ix=0 To b_no_texs-1

b_tex_id=file.ReadInt()

Next

brush_no=brush_no+1

new_tag=file.ReadTag()

Wend

Case NODE

new_tag=file.ReadTag()

n_name=B3DReadString(file)
n_px=file.ReadFloat()
n_py=file.ReadFloat()
n_pz=-file.ReadFloat() '*-1
n_sx=file.ReadFloat()
n_sy=file.ReadFloat()
n_sz=file.ReadFloat()
n_qw=file.ReadFloat()
n_qx=file.ReadFloat()
n_qy=file.ReadFloat()
n_qz=file.ReadFloat()

Local rot:Float[] = Quaternion.QuatToEuler(n_qx,n_qy,-n_qz,n_qw)
Local pitch#=rot[0]
Local yaw#=rot[1]
Local roll#=rot[2]
n_rx=-pitch
n_ry=yaw
n_rz=roll

new_tag=file.ReadTag()

If new_tag=NODE Or new_tag=ANIM

' make 'piv' entity a mesh, not a pivot, as B3D does


Local piv:TMesh=New TMesh
piv.classname="Model"

piv.name=n_name
piv.px=n_px
piv.py=n_py
piv.pz=n_pz
piv.sx=n_sx
piv.sy=n_sy
piv.sz=n_sz
piv.rx=n_rx
piv.ry=n_ry
piv.rz=n_rz
piv.qw=n_qw
piv.qx=n_qx
piv.qy=n_qy
piv.qz=n_qz

'piv.UpdateMat(True)
TEntity.entity_list.EntityListAdd(piv)
last_ent=piv

' root ent?
If root_ent=Null Then root_ent=piv
If node_level>0 Then piv.AddParent(parent_ent)

Endif

Case MESH

m_brush_id=file.ReadInt()
Local amesh:TMesh=New TMesh
last_ent=amesh
If root_ent=Null Then root_ent=amesh
If node_level>0 Then amesh.AddParent(parent_ent)

Case VRTS


v_flags=file.ReadInt()
v_tc_sets=file.ReadInt()
v_tc_size=file.ReadInt()
v_sz=12+v_tc_sets*v_tc_size*4
If v_flags & 1 Then v_sz=v_sz+12
If v_flags & 2 Then v_sz=v_sz+16

new_tag=file.ReadTag()

While NewTag(new_tag)<>True And file.Eof()<>True

v_x=file.ReadFloat()
v_y=file.ReadFloat()
v_z=file.ReadFloat()

If v_flags&1
v_nx=file.ReadFloat()
v_ny=file.ReadFloat()
v_nz=file.ReadFloat()
Endif

If v_flags&2
v_r=file.ReadFloat()'*255.0 ' *255 as surf.VertexColor() requires 0-255 values
v_g=file.ReadFloat()'*255.0
v_b=file.ReadFloat()'*255.0
v_a=file.ReadFloat()
Endif


'read tex coords...
For Local j=0 To v_tc_sets-1 ' texture coords per vertex - 1 for simple uv, 8 max
For Local k=1 To v_tc_size ' components per set - 2 for simple uv, 4 max
If k=1 v_u=file.ReadFloat()
If k=2 v_v=file.ReadFloat()
If k=3 v_w=file.ReadFloat()
Next
'If j=0 Or j=1 Then v_surf.VertexTexCoords(v_id,v_u,v_v,v_w,j)
Next

new_tag=file.ReadTag()

Wend



Case TRIS

Local vid0#, vid1#, vid2#

Local e:Bool = False
Local old_tr_brush_id:Int = tr_brush_id
tr_brush_id=file.ReadInt()


' don't create new surface if tris chunk has same brush as chunk immediately before it
If (prev_tag<>TRIS Or tr_brush_id<>old_tr_brush_id) ''??? Does switching brushes cause problems ???


Endif


tr_sz=12

new_tag=file.ReadTag()



Local num_tris:Int = ((size-4)/12) ''4=brush numer (int)

For Local j:Int=0 To num_tris-1

If file.Eof() Then new_tag=0; Print "**Error: early EOF"; Exit

tr_vid0=file.ReadInt()
tr_vid1=file.ReadInt()
tr_vid2=file.ReadInt()



new_tag=file.ReadTag()

totaltris+=1
Next

If new_tag<>TRIS


Endif


Case ANIM

a_flags=file.ReadInt()
a_frames=file.ReadInt()
a_fps=file.ReadFloat()

If a_frames<0 Then a_frames = -a_frames

If DEBUGMODEL Then Print "anim flags:"+a_flags+" frames:"+a_frames+" fps:"+a_fps

If mesh<>Null And file.Eof()<>True

mesh.anim=1

mesh.anim_seqs_first[0]=0
mesh.anim_seqs_last[0]=mesh.anim_seqs_last[0]+a_frames


Endif

Case BONE

Local ix:Int=0

new_tag=file.ReadTag()

While NewTag(new_tag)<>True And file.Eof()<>True And size<>0

bo_vert_id=file.ReadInt()
bo_vert_w=file.ReadFloat()

new_tag=file.ReadTag()

Wend
Print "Finding "+n_name
bo_bone = TBone(mesh.FindChild(n_name))
If bo_bone = Null Then Print "Null Bone"

bo_bone.keys.oldframes = bo_bone.keys.frames
bo_bone.keys.frames=bo_bone.keys.frames+a_frames
bo_bone.keys.flags=bo_bone.keys.flags.Resize(bo_bone.keys.frames+1)
bo_bone.keys.px=bo_bone.keys.px.Resize(bo_bone.keys.frames+1)
bo_bone.keys.py=bo_bone.keys.py.Resize(bo_bone.keys.frames+1)
bo_bone.keys.pz=bo_bone.keys.pz.Resize(bo_bone.keys.frames+1)
bo_bone.keys.sx=bo_bone.keys.sx.Resize(bo_bone.keys.frames+1)
bo_bone.keys.sy=bo_bone.keys.sy.Resize(bo_bone.keys.frames+1)
bo_bone.keys.sz=bo_bone.keys.sz.Resize(bo_bone.keys.frames+1)
bo_bone.keys.qw=bo_bone.keys.qw.Resize(bo_bone.keys.frames+1)
bo_bone.keys.qx=bo_bone.keys.qx.Resize(bo_bone.keys.frames+1)
bo_bone.keys.qy=bo_bone.keys.qy.Resize(bo_bone.keys.frames+1)
bo_bone.keys.qz=bo_bone.keys.qz.Resize(bo_bone.keys.frames+1)
If root_ent=Null Then root_ent=bo_bone
If node_level>0 Then bo_bone.AddParent(parent_ent)

If new_tag<>KEYS

last_ent=bo_bone


Endif







Case KEYS

k_flags=file.ReadInt()

new_tag=file.ReadTag()

While NewTag(new_tag)<>True And file.Eof()<>True And curSize <= size

k_frame=file.ReadInt()
k_frame = bo_bone.keys.oldframes+k_frame
curSize+=4

If(k_flags&1) 'pos
k_px=file.ReadFloat()
k_py=file.ReadFloat()
k_pz=-file.ReadFloat()
curSize+=12
Endif
If(k_flags&2) 'sca
k_sx=file.ReadFloat()
k_sy=file.ReadFloat()
k_sz=file.ReadFloat()
curSize+=12
Endif
If(k_flags&4) 'rot
k_qw=-file.ReadFloat()
k_qx=file.ReadFloat()
k_qy=file.ReadFloat()
k_qz=-file.ReadFloat()
curSize+=16

Endif

If bo_bone<>Null And k_frame < bo_bone.keys.frames ' check if bo_bone exists - it won't for non-boned, keyframe anims

bo_bone.keys.flags[k_frame]=bo_bone.keys.flags[k_frame]+k_flags
If(k_flags&1)
bo_bone.keys.px[k_frame]=k_px
bo_bone.keys.py[k_frame]=k_py
bo_bone.keys.pz[k_frame]=k_pz
Endif
If(k_flags&2)
bo_bone.keys.sx[k_frame]=k_sx
bo_bone.keys.sy[k_frame]=k_sy
bo_bone.keys.sz[k_frame]=k_sz
Endif
If(k_flags&4)
bo_bone.keys.qw[k_frame]=k_qw
bo_bone.keys.qx[k_frame]=k_qx
bo_bone.keys.qy[k_frame]=k_qy
bo_bone.keys.qz[k_frame]=k_qz
Endif

Endif

new_tag=file.ReadTag()

Wend

If new_tag<>KEYS

If bo_bone<>Null ' check if bo_bone exists - it won't for non-boned, keyframe anims


last_ent=bo_bone


Endif

Endif


Default

file.ReadByte()

End Select

Until file.Eof()


''clean up buffers
For Local e:TEntity = Eachin root_ent.GetChildren(True)

Local m:TMesh = TMesh(e)
If Not m Then continue

For Local surf:TSurface = Eachin m.surf_list
surf.CropSurfaceBuffers()
If m.anim_surf[surf.surf_id] Then m.anim_surf[surf.surf_id].CropSurfaceBuffers()
Next

Next


Return 1

End

')

And then add in Tanimation.monkey

format_code('
Class TAnimationKeys
Field oldframes:int '<-- this
')

What this does is if i load an animated model that only contains an idle anim and then pass LoadAnimSeq for run animation i can append the running animation in another file

e.g.

mesh = LoadAnimMesh("media/maleidle.b3d")
TModelB3D.LoadAnimSeq(mesh,"media/malerun.b3d")



I tested it, seems to work for me. But it needs some cleaning up.


Landon(Posted 2014) [#99]
also, i have to see how the animation is handled in the back end but i think you'd want to resize the sequence array

by changing this

format_code('
mesh.anim_seqs_first[0]=0
mesh.anim_seqs_last[0]=mesh.anim_seqs_last[0]+a_frames
')

To this

format_code('
local newlen:int = mesh.anim_seqs_first.Length()+1
mesh.anim_seqs_first=mesh.anim_seqs_first.Resize(newlen)
mesh.anim_seqs_last=mesh.anim_seqs_last.Resize(newlen)
mesh.anim_seqs_first[newlen-1]=mesh.anim_seqs_last[0]
mesh.anim_seqs_last[newlen-1]=mesh.anim_seqs_last[0]+a_frames-1
')

Then have some function to switch the meshes current sequence.


Deen(Posted 2014) [#100]
anyone have some sample codes of 3ds character (with animation - i know it is separated limb animation not bones) loaded into the minib3d-monkey?


Landon(Posted 2014) [#101]
format_code('
anyone have some sample codes of 3ds character (with animation - i know it is separated limb animation not bones) loaded into the minib3d-monkey?
')

if i'm not mistaken i don't think minib3d loads .3ds format ..yet

Also on a side note does anyone know why in html5 if i attach a model to a bone that it seems to bobble off and on the bone when i move the mesh around? it looks like the positoning update is not in sync with the renderer.




Landon(Posted 2014) [#102]
Hmm seems to sort itself out if i set the FPS lower... i guess the Renderer is going faster than the Update..


Landon(Posted 2014) [#103]
I was able to clean the LoadAnimSeq code up a bit more... you can literally just Copy Pasta the below code and it works

Add this field to TAnimationKeys in TAnimation.monkey

format_code('
Class TAnimationKeys
Field oldframes:int

')


Paste into Tmodelb3d.monkey TModelB3D class

format_code('

Function LoadAnimSeq:Int(mesh:TMesh,f_name$)

Local data:DataBuffer = DataBuffer.Load(FixDataPath(f_name))

If DEBUGMODEL Then Print"..loading B3DBinary:"+FixDataPath(f_name)

If Not data Or (data And data.Length() <=1)
Print "**File not found: "+f_name
Return -1
Endif

Return ParseB3DAnim(mesh, data)

end


Function ParseB3DAnim:int(mesh:TMesh, data:DataBuffer, override_texflags:Int=-1)
' Header info

Local tag:Int
Local prev_tag:Int
Local new_tag:Int
Local vno:Int

Local file:BufferReader = BufferReader.Create(data)

''read BB3D

tag=file.ReadTag()

If DEBUGMODEL Then Print "TModel "+PrintTag(tag)

vno =file.ReadInt() 'tag
vno =file.ReadInt() 'size

vno =file.ReadInt() 'version

If tag<>BB3D Print "Invalid b3d file"; Return -1
If Int(vno*0.01) >0 Print "Invalid b3d file version"; Return -1

' Locals

Local size:Int
Local curSize:Int
Local node_level:Int=-1
Local old_node_level:Int=-1
Local node_pos:Int[100]





' node local vars
Local n_name$=""
Local n_px#=0
Local n_py#=0
Local n_pz#=0
Local n_sx#=0
Local n_sy#=0
Local n_sz#=0
Local n_rx#=0
Local n_ry#=0
Local n_rz#=0
Local n_qw#=0
Local n_qx#=0
Local n_qy#=0
Local n_qz#=0



' anim local vars
Local a_flags:Int
Local a_frames:Int
Local a_fps:Int

' bone local vars
Local bo_bone:TBone
Local bo_no_bones:Int
Local bo_vert_id:Int
Local bo_vert_w#

' key local vars
Local k_flags:Int
Local k_frame:Int
Local k_px#
Local k_py#
Local k_pz#
Local k_sx#
Local k_sy#
Local k_sz#
Local k_qw#
Local k_qx#
Local k_qy#
Local k_qz#

Local parent_ent:TEntity=Null ' parent_ent - used to keep track of parent entitys within model, separate to parent_ent_ext paramater which is external to model
Local root_ent:TEntity=Null

Local last_ent:TEntity=Null ' last created entity, used for assigning parent ent in node code

Local totaltris:Int=0

' Begin chunk (tag) reading

Repeat

new_tag=file.ReadTag()

If NewTag(new_tag)=True

prev_tag=tag
tag=new_tag

file.ReadInt() 'tag
size=file.ReadInt() 'size
curSize=0
endif

Select tag

Case NODE

new_tag=file.ReadTag()

n_name=B3DReadString(file)
n_px=file.ReadFloat()
n_py=file.ReadFloat()
n_pz=-file.ReadFloat() '*-1
n_sx=file.ReadFloat()
n_sy=file.ReadFloat()
n_sz=file.ReadFloat()
n_qw=file.ReadFloat()
n_qx=file.ReadFloat()
n_qy=file.ReadFloat()
n_qz=file.ReadFloat()

Local rot:Float[] = Quaternion.QuatToEuler(n_qx,n_qy,-n_qz,n_qw)
Local pitch#=rot[0]
Local yaw#=rot[1]
Local roll#=rot[2]
n_rx=-pitch
n_ry=yaw
n_rz=roll

new_tag=file.ReadTag()


Case ANIM

a_flags=file.ReadInt()
a_frames=file.ReadInt()
a_fps=file.ReadFloat()

If a_frames<0 Then a_frames = -a_frames

If DEBUGMODEL Then Print "anim flags:"+a_flags+" frames:"+a_frames+" fps:"+a_fps

If mesh<>Null And file.Eof()<>True

mesh.anim=1

local newlen:int = mesh.anim_seqs_first.Length()+1
mesh.anim_seqs_first = mesh.anim_seqs_first.Resize(newlen)
mesh.anim_seqs_last = mesh.anim_seqs_last.Resize(newlen)
mesh.anim_seqs_first[newlen-1]=mesh.anim_seqs_last[0]
mesh.anim_seqs_last[newlen-1]=mesh.anim_seqs_last[0]+a_frames

Endif

Case BONE

Local ix:Int=0

new_tag=file.ReadTag()

While NewTag(new_tag)<>True And file.Eof()<>True And size<>0

bo_vert_id=file.ReadInt()
bo_vert_w=file.ReadFloat()

new_tag=file.ReadTag()

Wend
Print "Finding "+n_name
bo_bone = TBone(mesh.FindChild(n_name))
If bo_bone = Null Then Print "Null Bone"

bo_bone.keys.oldframes = bo_bone.keys.frames
bo_bone.keys.frames=bo_bone.keys.frames+a_frames
bo_bone.keys.flags=bo_bone.keys.flags.Resize(bo_bone.keys.frames+1)
bo_bone.keys.px=bo_bone.keys.px.Resize(bo_bone.keys.frames+1)
bo_bone.keys.py=bo_bone.keys.py.Resize(bo_bone.keys.frames+1)
bo_bone.keys.pz=bo_bone.keys.pz.Resize(bo_bone.keys.frames+1)
bo_bone.keys.sx=bo_bone.keys.sx.Resize(bo_bone.keys.frames+1)
bo_bone.keys.sy=bo_bone.keys.sy.Resize(bo_bone.keys.frames+1)
bo_bone.keys.sz=bo_bone.keys.sz.Resize(bo_bone.keys.frames+1)
bo_bone.keys.qw=bo_bone.keys.qw.Resize(bo_bone.keys.frames+1)
bo_bone.keys.qx=bo_bone.keys.qx.Resize(bo_bone.keys.frames+1)
bo_bone.keys.qy=bo_bone.keys.qy.Resize(bo_bone.keys.frames+1)
bo_bone.keys.qz=bo_bone.keys.qz.Resize(bo_bone.keys.frames+1)
If root_ent=Null Then root_ent=bo_bone
If node_level>0 Then bo_bone.AddParent(parent_ent)

If new_tag<>KEYS

last_ent=bo_bone


Endif




Case KEYS

k_flags=file.ReadInt()

new_tag=file.ReadTag()

While NewTag(new_tag)<>True And file.Eof()<>True And curSize <= size

k_frame=file.ReadInt()
k_frame = bo_bone.keys.oldframes+k_frame
curSize+=4

If(k_flags&1) 'pos
k_px=file.ReadFloat()
k_py=file.ReadFloat()
k_pz=-file.ReadFloat()
curSize+=12
Endif
If(k_flags&2) 'sca
k_sx=file.ReadFloat()
k_sy=file.ReadFloat()
k_sz=file.ReadFloat()
curSize+=12
Endif
If(k_flags&4) 'rot
k_qw=-file.ReadFloat()
k_qx=file.ReadFloat()
k_qy=file.ReadFloat()
k_qz=-file.ReadFloat()
curSize+=16

Endif

If bo_bone<>Null And k_frame < bo_bone.keys.frames ' check if bo_bone exists - it won't for non-boned, keyframe anims

bo_bone.keys.flags[k_frame]=bo_bone.keys.flags[k_frame]+k_flags
If(k_flags&1)
bo_bone.keys.px[k_frame]=k_px
bo_bone.keys.py[k_frame]=k_py
bo_bone.keys.pz[k_frame]=k_pz
Endif
If(k_flags&2)
bo_bone.keys.sx[k_frame]=k_sx
bo_bone.keys.sy[k_frame]=k_sy
bo_bone.keys.sz[k_frame]=k_sz
Endif
If(k_flags&4)
bo_bone.keys.qw[k_frame]=k_qw
bo_bone.keys.qx[k_frame]=k_qx
bo_bone.keys.qy[k_frame]=k_qy
bo_bone.keys.qz[k_frame]=k_qz
Endif

Endif

new_tag=file.ReadTag()

Wend

If new_tag<>KEYS

If bo_bone<>Null ' check if bo_bone exists - it won't for non-boned, keyframe anims


last_ent=bo_bone


Endif

Endif


Default

file.ReadByte()

End Select

Until file.Eof()


Return mesh.anim_seqs_first.Length()

End
')


Now you can use the sequence variable in Animate Function e.g.
format_code('
local runloop:int = TModelB3D.LoadAnimSeq(mesh,"media/malerun.b3d")
mesh.Animate(1,1,runloop)
')


AdamRedwoods(Posted 2014) [#104]
Also on a side note does anyone know why in html5 if i attach a model to a bone that it seems to bobble off and on the bone when i move the mesh around? it looks like the positoning update is not in sync with the renderer.

yes, are you using entity.AddParent() or are you using global X,Y,Z positioning? Parenting should not bobble.

I was able to clean the LoadAnimSeq code up a bit more...

Cool! thanks for this. i'll add it in.

anyone have some sample codes of 3ds character (with animation - i know it is separated limb animation not bones) loaded into the minib3d-monkey?

sorry, no 3DS yet, although i reached out to Warner from the blitzmax forums and he said we can use his 3DS importer code to be included. it should be mostly compatible, i'll have to review it.
...but with that said, i still feel my time is best spent finishing the collada importer, but i am open to suggestions.


Landon(Posted 2014) [#105]

yes, are you using entity.AddParent() or are you using global X,Y,Z positioning? Parenting should not bobble



I used entityparent...is addparent different?

also is there a polygon limit for box to poly collisions? I can not get my player to collide with the walls of my map for the life of me. I can send the mesh if you want to look.


AdamRedwoods(Posted 2014) [#106]
I used entityparent...is addparent different?

same thing. is UpdateWorld() the last thing you call? i don't know how objects parented to bones are lagging, but i'll look into it.

also is there a polygon limit for box to poly collisions?

yes, but i don't think there is any box->poly collisions. only sphere->poly, sphere->sphere, sphere->box, sphere->multisphere, multisphere->ETC.


Landon(Posted 2014) [#107]

yes, but i don't think there is any box->poly collisions. only sphere->poly, sphere->sphere, sphere->box, sphere->multisphere, multisphere->ETC.



Ok i got the collisions to work, i had a brain fart and left the box size values in the function call for POLYGON type. But i am noticing that i am bumping into invisible objects when i walk around, they don;t stop me but they alter my trajectory when i walk. I am using Sphere to Poly collision. it could be from the constant downward moveentity command for gravity. i think once the player touches the floor i should turn that off until they are no longer colliding with it. I'd have to check.

But yea i noticed that if i use bone animation on a model and then entityparent the helmet to the head bone. it bobbles as i walk until i stand still. it goes away if i set the update rate at or below the actual fps i am getting. I am using the MiniB3DApp class and my UpdateWorld() is in the Update Method... should i put it in the OnUpdate() method?


Landon(Posted 2014) [#108]
Ok i found the problem with the bobbling entities attached to a bone, it seems the update skips any children of bones in TEntity UpdateChildren Method

if you Add the below function in TEntity.UpdateChildren after the TBone UpdateMatrix method it solves the problem.
format_code('
TBone(ent_c).UpdateMatrix(ent_c.loc_mat)
UpdateChildren(ent_c,type)'<----- This
')


Landon(Posted 2014) [#109]
Oh and i got the collision problem sorted out it was the downward force against odd polygons that were causing it.




AdamRedwoods(Posted 2014) [#110]
it seems the update skips any children of bones in TEntity UpdateChildren Method

cool. i'll need to look into that, it actually should catch it in the TAnimation, but i'll review this and see if i can't consolidate the Matrix chain updating.

nice screenshot!
also, it looks like your frame rate is a bit low, that is because i really need to put in an octree for collisions and frustum culling. coming soon!


Landon(Posted 2014) [#111]
oh actually my SetUpdateRate is at 20 intentionally, i forgot to change it back to 30 after finding the problem with the bobbling helmet. i think i average close to 30 fps.


Landon(Posted 2014) [#112]
Does html5 support texture blending at all? Lightmapping doesn't seem to work.

GLFW


HTML5



Landon(Posted 2014) [#113]
Oh ya derp.. before i forget there was a bug in that loadanimseq code i posted.. if you didn;t notice it. This is the fixed code which needs to replace that section in ParseB3DAnim Method

format_code('
Case ANIM

a_flags=file.ReadInt()
a_frames=file.ReadInt()
a_fps=file.ReadFloat()

If a_frames<0 Then a_frames = -a_frames

Print "anim flags:"+a_flags+" frames:"+a_frames+" fps:"+a_fps

If mesh<>Null And file.Eof()<>True

mesh.anim=1

local newlen:int = mesh.anim_seqs_first.Length()+1
mesh.anim_seqs_first = mesh.anim_seqs_first.Resize(newlen)
mesh.anim_seqs_last = mesh.anim_seqs_last.Resize(newlen)
mesh.anim_seqs_first[newlen-1]=mesh.anim_seqs_last[newlen-2]+1
mesh.anim_seqs_last[newlen-1]=mesh.anim_seqs_last[newlen-2]+a_frames
')


AdamRedwoods(Posted 2014) [#114]
Does html5 support texture blending at all? Lightmapping doesn't seem to work.

it should work. can you describe your model's texture layer sequence and texture flags?
note that i set a max texture limit of 4 on html5. if people need more i can set a dynamic compiler for >4 textures.


Landon(Posted 2014) [#115]
i'm using gile[s] this is their texture settings, the texture blend for the lightmap is set to MultiplyX2 and the normal texture i believe is just on default blending or multiply. But the lightmapping seems to work on OUYA as well, the only target that it doesn;t work under that i can test is html5. i haven't checked flash yet.

Here is output when loading:

-Load Texture:0 oldroof.jpg blend:2 coords:0
-Load Texture:1 ometalwall4.jpg blend:2 coords:0
-Load Texture:2 windowatrans.png blend:2 coords:0
-Load Texture:3 ometalwall3.jpg blend:2 coords:0
-Load Texture:4 oldtilefloor1.jpg blend:2 coords:0
-Load Texture:5 ometalwall1.jpg blend:2 coords:0
-Load Texture:6 teleporter.jpg blend:2 coords:0
-Load Texture:7 ometalwall2.jpg blend:2 coords:0
-Load Texture:8 Magic Lightmap 0.png blend:5 coords:1
-Load Texture:9 Magic Lightmap 1.png blend:5 coords:1
-Load Texture:10 Magic Lightmap 2.png blend:5 coords:1
-Load Texture:11 Magic Lightmap 3.png blend:5 coords:1
-Load Texture:12 Magic Lightmap 4.png blend:5 coords:1
-Load Texture:13 Magic Lightmap 5.png blend:5 coords:1
-Load Texture:14 Magic Lightmap 6.png blend:5 coords:1
-Load Texture:15 Magic Lightmap 7.png blend:5 coords:1
-Load Texture:16 Magic Lightmap 8.png blend:5 coords:1



Landon(Posted 2014) [#116]
Ok i sort of fixed the problem..

the built in shader was missing an if case for blend mode 5, i copy pasta'd what you have there it works but it's way too bright.

Added this to basicshadersgl.monkey in the FRAGBLEND String before the return statement.
format_code('
"} else if(blend==5.0) { color = (vertcolorx * texture); return finalcolor+color;"+
')

I'm a newb when it comes to GLSL shaders, what should i put for multiply x2?




AdamRedwoods(Posted 2014) [#117]
yes, >4 textures, so i'll have to allow dynamically compiling shaders for html5 (opengl2.0)


Landon(Posted 2014) [#118]
Here we go this change makes it look almost completely correct.

format_code('
"} else if(blend==5.0) { color = (vertcolorx * texture); return finalcolor*color;"+
')




Landon(Posted 2014) [#119]
got this issue where if i have a texture in my map that has alpha transparency, the entire map has a weird z ordering problem where i can see through the walls. i can't seem to figure out how to fix that.


blabz(Posted 2014) [#120]
Great work Adam!
I've been updating minib3d for blitzmax as I've already created something with it and wanted to see how you calculated your tangents for normals mapping. I noticed you're putting these in the color vbo which coincidentally I decided to do the same.

I've added shadowmapping with PCF, SSAO, and BLOOM, which in theory should be easily integrated to monkey minib3d.

It'd be great if there was a ES 3.0 module so we could take advantage of hardware MSAA with blitframebuffer, makes a huge difference.


AdamRedwoods(Posted 2014) [#121]
got this issue where if i have a texture in my map that has alpha transparency, the entire map has a weird z ordering problem where i can see through the walls. i can't seem to figure out how to fix that.

yes, if an entity has alpha, it needs to be sorted by distance to camera, and then rendered from back to front. the distance is measured from the CENTER of the BOUNDING BOX MESH. larger objects tend to get messed with this more often.

one way to get around this is to break up the level into smaller parts, or at least those that use alpha. the other way is to have the engine sort by triangles, but i find most engines don't sort triangles (slow), so miniB3D doesn't either.


Landon(Posted 2014) [#122]
what's weird is i thought for sure i exported the mesh as multiple meshes within the file, but it looks as though i'll have to export the parts with alpha as an entirely different file.

this is a big pain in the butt and your a bad person for making me do this.


/sarcasm


AdamRedwoods(Posted 2014) [#123]
this is a big pain in the butt and your a bad person for making me do this.

it's true, i am bad for not finishing the collada importer, which may make everyone's lives easier. :^)


Sammy(Posted 2014) [#124]
On a similar note...

Have you seen this Adam, I believe it converts FBX/Collada/OBJ to JSON format. Making writing an importer a lot easier.

https://github.com/libgdx/fbx-conv


AdamRedwoods(Posted 2014) [#125]
I've been updating minib3d for blitzmax as I've already created something with it and wanted to see how you calculated your tangents for normals mapping.

i do it in the vertex shader after updating the mesh with SetNormalMapping(single_surf:TSurface=Null).
format_codebox('
/*-- tangent in aColors, cross to find bitangent*/
if ((texflag > 0.0) && (texfxNormal[0] > 0.0)) {
vec3 tangent = normalize(mMatrix*aColors).xyz;
vec3 bitangent = normalize( cross( normal.xyz, tangent.xyz ));
mat3 nmMat = mat3( tangent.x, bitangent.x, normal.x,tangent.y, bitangent.y, normal.y,tangent.z, bitangent.z, normal.z);
nmLight = nmMat * nmLight;
}
')

I've added shadowmapping with PCF, SSAO, and BLOOM, which in theory should be easily integrated to monkey minib3d.

yes absolutely, if you're willing to zlib/mit your code. otherwise i am planning to write these shaders.
Here we go this change makes it look almost completely correct.

blend mode 5 looks like it brightens/darkens on a greyscale texture, where 0.5 does nothing.
format_code('
else if(blend==5.0) { color = (vertcolorx * 2.0*texture); return clamp(finalcolor*color,0.0,1.0);
')


Landon(Posted 2014) [#126]
So i'm running across this weird issue where in my editor which i created using bmax and minib3d i've assembled a level together and i save it as an xml file. Then when i load it in monkey everything is in the wrong position other than the lights and cameras..

I think the meshes that are loaded are offset somehow but looking through the code i can;t put my finger on it. even if i reverse coordinates it's still off by half the amount.

In the screenshot below the Left view is my editor viewport with an In-Game cam view showing where the camera is positioned and pointed, the view on the right is the same scene in monkey minib3d but the camera is in a totally different spot. Even though the positions and rotations are the same, which leads me to believe the mesh is the entity that is offset somehow.




Landon(Posted 2014) [#127]
Nevermind... I uh herped so hard i derped.. i set collisions before positioning.....




blabz(Posted 2014) [#128]
yes absolutely, if you're willing to zlib/mit your code. otherwise i am planning to write these shaders.


Yah, most of the code I've used is a combination of things I've found in books and online with a minor personal touch.

Does monkey miniB3D already have support for post-processing shaders? Using one FBO as an uniform for another FBO?

Also, my shadow mapping isn't omnidirectional, did you plan on have this render to a cubemap?


Barang Greenback(Posted 2014) [#129]
hi
im trying to create and edit textures
this code works in html5
format_code('
Local pix:TPixmap = TPixmap.CreatePixmap(64,64) ''must be powers-of-two
Local x:Int = 20, y:Int=20
Local color:Int = $ff0000ff '' ABGR
For Local x:Int=0 To 15
pix.SetPixel(x,4,Rand(0,255),Rand(0,255),Rand(0,255),255)
Next

''when done
Local tex:TTexture = TTexture.LoadTexture(pix, 1) 'flags 9=1+8=color+mipmapping
')
but Im only exporting to flash and I want my games to be held in one single file.
when I run it in flash, the "tpixmap_flash.monkey" file opens and I get the error "Unable to find overload for _WritePixel(FlashPixmap,Int,Int,Int)."
can someone point me in the right direction?


AdamRedwoods(Posted 2014) [#130]
I get the error "Unable to find overload for _WritePixel(FlashPixmap,Int,Int,Int)."

BUG!
fixed, on github. you only need the file flash11/tpixmap_flash.monkey.


Does monkey miniB3D already have support for post-processing shaders? Using one FBO as an uniform for another FBO?
Also, my shadow mapping isn't omnidirectional, did you plan on have this render to a cubemap?

yes, yes, no on omnidirectional. not worth the overhead and mobile isn't fast enough yet.

pre/post interface per camera:
format_code('''
'' standard pre/post per camera
''
Interface IShaderProcess

Method PreProcess:Int(cam:TCamera) ''run before all rendering (ie. clear framebuffer)

Method PostProcess:Int(cam:TCamera) ''run after all rendering (ie. draw framebuffer, blur, etc)

End')


Barang Greenback(Posted 2014) [#131]
I dont get that error anymore cheers, but I still cant get it to run with"
pix.SetPixel(x,4,Rand(0,255),Rand(0,255),Rand(0,255))
"
uncommented

it comes up with "

Loading configuration file C:\flex_sdk_4.6\frameworks\flex-config.xml
C:\MonkeyPro75d\bananas\zzz\cb.build\flash\MonkeyGame.as(18003): col: 20 Error: Implicit coercion of a value of type void to

an unrelated type MonkeyGame.as$30:TPixmap.

m_pixels=TPixmap.WritePixel(m_pixels,t_x,t_y,t_a<<24|t_r<<16|t_b<<8|t_g);
^

TRANS FAILED: Error executing 'mxmlc -static-link-runtime-shared-libraries=true MonkeyGame.as', return code=1
Done.

"
in the console

is this maybe because im using an incompatible version of monkey?
im using 75d
would 73b or something be better?
Thanks for your time


AdamRedwoods(Posted 2014) [#132]
Error: Implicit coercion of a value of type void

i was being dumb, apologies. this time i fixed it AND tested it.
fixed on github. same file.


Barang Greenback(Posted 2014) [#133]
Yeah!! it worked 1st time with 0.424b
its just the same as html5 now.
I can work on adding textures instead of vertex colors now
Thanks so much.


thehawk2323(Posted 2014) [#134]
Where can I find documentation on all functions?


blabz(Posted 2014) [#135]
Hi Adam,

I think you tangent calculations are a little off - I think you want something more like this - it averages the normals.

format_code('
Local tempTangent:TVector[] = New TVector[no_verts]
Local tempBinormal:TVector[] = New TVector[no_verts]

For Local x:Int = 0 Until no_verts
tempTangent[x] = New TVector
tempBinormal[x] = New TVector
Next

For Local i:Int = 0 Until no_tris

'Local tri_no:Int = (i+1)*3
Local vid0:Int= TriangleVertex(i,0) 'tris[tri_no-1]
Local vid1:Int= TriangleVertex(i,1) 'tris[tri_no-2]
Local vid2:Int= TriangleVertex(i,2) 'tris[tri_no-3]

Local v0:TVector = TVector.Create(VertexX(vid0),VertexY(vid0),VertexZ(vid0))
Local v1:TVector = TVector.Create(VertexX(vid1),VertexY(vid1),VertexZ(vid1))
Local v2:TVector = TVector.Create(VertexX(vid2),VertexY(vid2),VertexZ(vid2))

Local q1:TVector = v1.Subtract(v0)
Local q2:TVector = v2.Subtract(v0)

Local s1:Float = VertexU(vid1) - VertexU(vid0)
Local s2:Float = VertexU(vid2) - VertexU(vid0)
Local t1:Float = VertexV(vid1) - VertexV(vid0)
Local t2:Float = VertexV(vid2) - VertexV(vid0)


Local tangent:TVector = q1.Multiply(t2).Subtract(q2.Multiply(t1))
tangent.Normalize()
Local binormal:TVector = q1.Multiply(-s2).Add(q2.Multiply(s1))
binormal.Normalize()


For Local j:Int = 0 To 2
tempTangent[TriangleVertex(i,j)] = tempTangent[TriangleVertex(i,j)].Add(tangent)
tempBinormal[TriangleVertex(i,j)] = tempBinormal[TriangleVertex(i,j)].Add(binormal)
Next

Next

vert_tang = New Float[vert_col.length]

For Local i:Int = 0 Until no_verts

Local VNormal:TVector = TVector.Create(VertexNX(i),VertexNY(i),VertexNZ(i))

Local t:TVector = tempTangent[i]

t = t.Subtract(VNormal.Multiply(t.Dot(VNormal)))
't = t.Subtract(VNormal.Multiply(VNormal.Dot(t)))
t.Normalize()
vert_tang[(i*4)] = t.x
vert_tang[(i*4)+1] = t.y
vert_tang[(i*4)+2] = t.z


If VNormal.Cross(t).Dot(tempBinormal[i]) < 0.0
vert_tang[(i*4)+3] = -1.0
Else
vert_tang[(i*4)+3] = 1.0
EndIf

Next
')


Barang Greenback(Posted 2014) [#136]
Hello Adam,
It wasnt apparent at 1st because the 1st textures i made were flesh
colored or grey, but when i converted textures with a blue hue they came
out with a green hue, the sky and lights were all green.

I think blue and green have been swapped with a typo maybe

I changed setpixel in tpixmap_flash.monkey from

format_code('
Method SetPixel:Void(x:Int,y:Int,r:Int,g:Int,b:Int,a:Int=255)
_WritePixel(pixels,x,y, (a Shl 24)|(r Shl 16)|(b Shl 8)|g )
End
')

to
format_code('
Method SetPixel:Void(x:Int,y:Int,r:Int,g:Int,b:Int,a:Int=255)
_WritePixel(pixels,x,y, (a Shl 24)|(r Shl 16)|(g Shl 8)|b )
End
')

and now It all looks just like html5 now
Could you recheck it and update if ness, but i also noticed that you have
a comment saying "'' **FLASH BITMAPS TEXTURES ARE BGRA ?? maybe" so im not
sure.


AdamRedwoods(Posted 2014) [#137]
Where can I find documentation on all functions?

here is the blitz3d functions, but doesn't have all the new stuff i have put in:
http://blitzmax.com/b3ddocs/command_list_3d_cat.php
Documentation is on my TODO.

I think you tangent calculations are a little off - I think you want something more like this - it averages the normals.

probably, it also appears i left myself a note in my original function to average the norms, so i'll test this out.

I think blue and green have been swapped with a typo maybe

ok, i'll test it out.

thanks for the updates everyone!


AdamRedwoods(Posted 2014) [#138]
my octree performance so far: ~25ms to parse 24000 sphere meshes out of 150000. (i5 laptop win8)
it gets too slow to add objects >200000.

does this seem right? i thought it would be faster.


Sammy(Posted 2014) [#139]
Have you compared it to a brute-force method to see how it compares?


blabz(Posted 2014) [#140]
Very cool Adam, did you find this method on Gamasutra?


AdamRedwoods(Posted 2014) [#141]
this will be faster than brute-force no matter what, as brute-force has to go through every object. a different "broadphase" would be just to create a user-defined 3d grid for storing objects in it.

i created the octree myself, although probably would be faster to copy someone else.
nonetheless, i found the speed problem was due to my bin capacity initial setting at "8". setting it higher speeds everything up, but still slows down when adding (but not getting) >200,000 objects. i'm shooting for a cool million. hmmm...


Sammy(Posted 2014) [#142]
I was suggesting brute-force for comparison only, a starting point so-to-speak. I use the simple 3D grid in my own program, its good but becomes more inefficient the larger your cull area gets. Octrees shouldn't have this problem I assume?


EdzUp(Posted 2014) [#143]
Adam: I have got to the hyperspace section of Star Rogue and I can hyperspace five times before I run out of ram on device. I am running through the entire lists for the game and using object.FreeEntity() to release the meshes and FreeTexture to free textures before creating the new star system, is there a garbage collection problem with minib3d entities or is there something else we need to do?


AdamRedwoods(Posted 2014) [#144]
is there a garbage collection problem with minib3d entities or is there something else we need to do?

could be some leaks. i know that surfaces are not released, maybe i need a reference counter on them to do a hardware release. pixmaps have a reference counter, i'd have to make sure they are releasing properly too. i'll add it to my TODO list, but for now, when you free a mesh, free the surfaces first.


Sammy(Posted 2014) [#145]
Apart from the non power of 2 is there any other reason that a texture would be automatically resized Adam? I'm getting a kind of moire pattern bad rescale interference on my 1024x1024 PNG textures in-game?


AdamRedwoods(Posted 2014) [#146]
Apart from the non power of 2 is there any other reason that a texture would be automatically resized Adam?

all textures are resized for mipmapping, but yes, if they are a power-of-two then they are not resized for the first level.

there are texture functions you can use: texture.ResizeSmooth() and texture.ResizeNoSmooth() for dealing with resizing.
texture.Smooth() and texture.NoSmooth() controls mipmapping on/off.


Sammy(Posted 2014) [#147]
Ah, I think it may be the mip mapping rescale, as the moire effect seems a little less pronounced the closer the texture is to the camera. I'll try the different settings.


Sammy(Posted 2014) [#148]
Quick Question:

My tablet is not available to test this but I'm wondering if I export my object to .OBJ, do I need to ensure that the .OBJ file exporter converts all quads to triangles. I seem to remember that GLES 2 has no quad primitive. Does the .OBJ importer take this into account or do I need to take this into consideration while converting my meshes for MB3D importing?


AdamRedwoods(Posted 2014) [#149]
if I export my object to .OBJ, do I need to ensure that the .OBJ file exporter converts all quads to triangles.

nope, should handle all polys and auto-triangulates on import. the upcoming collada importer does this, too.


Sammy(Posted 2014) [#150]
That's good, thanks Adam. :)

One thing I noticed is that the associated .MTL file, when Tmodelobj.monkey tries to load it, has not got a path by the time it hits the ParseMTLLib() method, only a file name? So it reports that the MTL file is not found for me(my .OBJ files are within a sub folder. I realise it also adds a .txt ext. BTW ;) ). I tried adding a path to the .OBJ files "mtllib" field but to no avail here.

Thinking further ahead, will I also need to pre-parse this .MTL file for textures that need to be preloaded too?


AdamRedwoods(Posted 2014) [#151]
So it reports that the MTL file is not found for me

hmmmm. it should be the same. it adds the .txt to the mtl file if it doesn't find the file.
Oh, BTW i do this all the time, i forget to add "mtl" to the accepted binary files that Monkey copies over. #BINARY_FILES += "*.mtl"
maybe you're already doing that.

will I also need to pre-parse this .MTL file for textures that need to be preloaded too?

OBJ loader will load textures according to what is in the MTL file.


Sammy(Posted 2014) [#152]
Ok, thanks again Adam. I'm in bed now but I'll be sure to check the things you mentioned first thing tomorrow.


Rone(Posted 2014) [#153]

Apart from the non power of 2 is there any other reason that a texture would be automatically resized Adam? I'm getting a kind of moire pattern bad rescale interference on my 1024x1024 PNG textures in-game?


hey,
can you upload the image, wherein the scaling algorithm creates the moiré pattern...?


Sammy(Posted 2014) [#154]
Well TBH, it's not easy, the scaling problem is most evident when a quad is facing the camera and you are actually moving towards it. I'll try and create a checker-board texture to see if it a bit more easy to see in a static shot.

Some other details.

I'm applying the texture myself to the mesh after loading, not using B3D or OBJ .Mat auto texture loading.
As such I'm applying the mip map flags ect.
This affects GLFW but not HTML5
Textures are all ^2, 24bit rgb PNGs


Sammy(Posted 2014) [#155]
Seems that ONLY the .MTL filename is being passed on, not with the needed path. I added this (**) line to extract the path+filename minus the extension. Then added ".mtl" to create a new .MTL filename based on the .OBJ filename. Its a bit of a fudge but it seems to work. Not fully tested though, as another rendering error in my code is giving me problems now but it seems to find and parse the .MTL file AFAIK.

("tmodelobj.monkey")
format_code(' Function LoadMesh:TMesh(url:String, flags:Int=-1)

override_texflags = flags

Local mesh:TMesh = ParseObj(LoadString(url), flags, LoadString(url[ .. - 3] + "mtl")) ' ** Now includes mtllib param **

If mesh = Null Then Print "**File not found " + url ElseIf DEBUG Then Print "TModelObj: " + url
If mesh Then mesh.name = url

Return mesh

End')


AdamRedwoods(Posted 2014) [#156]
that will probably work in most situations, but OBJ files embed the mtl filename in the obj file.
it seems i dropped the ball and didn't move the url path to the ParseMTLLIB function, thanks for pointing that out.

fixed tmodelobj.monkey, up on github.


Sammy(Posted 2014) [#157]
NP, thanks for the quick patch.


Sammy(Posted 2014) [#158]
My .OBJ files were still not working but I noticed that the .OBJ file importer was expecting a single space between the OBJ file commands. 3DSMax .OBJ exporter actually varies the amount of spaces between the OBJ file command and params.

You will notice in my 3DSMax .OBJ file export a vertex has 2 spaces between the command and its params.
format_code('v 850.205750 -70.137939 637.771790')
What ParseObj() is expecting all .OBJs to be... 1 space.
format_code('v 850.205750 -70.137939 637.771790')
.Which is not strictly part of the .OBJ file format.

I added this line...
format_code('While Line.Contains(" "); Line = Line.Replace(" ", " "); Wend ' **(Added to strip space sequences down to a space)**')

This strips any sequences of more than one space down to one, which is the format the importer is expecting. This works across the whole file, including normals, texture coords ect.

The full function.
format_codebox(' Function ParseObj:TMesh(s:String, flags:Int=-1, mtllib_string:String = "")

Local stream:TModelObj = New TModelObj

stream.data = s
stream.length = stream.data.Length()

Local StreamLine:Int=0
If stream.length =0
Return Null
Endif

If DEBUG Then Print""

Local matlibs:StringMap<TObjMtl> = New StringMap<TObjMtl>
Local vertexP:TObjVertex[MAXVERTS]
Local vertexN:TObjNormal[MAXVERTS]
Local vertexT:TObjTexCoord[MAXVERTS]
Local faces:TFaceData[MAXVERTS]

Local gname:String = ""
Local snumber:Int = -1
Local curmtl:String = ""
Local Readface:Bool = True
Local vertsAdded:Bool = False
Local hasNorms:Int = 0

Local VC:Int = 0
Local VN:Int = 0
Local VT:Int = 0
Local FC:Int = 0
Local TRI:Int = 0
Local SC:Int = 0


Local mesh:TMesh = TMesh.CreateMesh()
Local surface:TSurface
Local surfaceCache:Int[] = New Int[255]
Local mtlCache:String[] = New String[255]
Local currMtl:TObjMtl

'mesh.name = url

While stream.pos < stream.length

Local Line:String = stream.ReadLine().Trim()

If Line.Length() < 1 Then Continue

While Line.Contains(" "); Line = Line.Replace(" ", " "); Wend ' **(Added to strip space sequences down to a space)**

If Line[0] = "#" Then

If DEBUG Then Dprint(".Obj Comment : " + Line)

Else

Local tag:String = Line[0..9].ToLower()

If tag[0..2]= "o " Then
mesh.name = Line[2..]
Endif

If tag[0..2]= "v " Then
If VC>=vertexP.Length()-1 Then vertexP = vertexP.Resize(vertexP.Length()+MAXVERTS)

vertexP[VC+1] = New TObjVertex
vertexP[VC+1].GetValues(Line[2..])
VC+=1
Endif

If tag[0..3] = "vn " Then
If VN>=vertexN.Length()-1 Then vertexN = vertexN.Resize(vertexN.Length()+MAXVERTS)

vertexN[VN+1] = New TObjNormal
vertexN[VN+1].GetValues(Line[3..])
VN+=1
hasNorms = 1
Endif

If tag[0..3] = "vt " Then
If VT>=vertexT.Length()-1 Then vertexT = vertexT.Resize(vertexT.Length()+MAXVERTS)

vertexT[VT+1] = New TObjTexCoord
vertexT[VT+1].GetValues(Line[3..])
VT+=1
Endif

If tag[0..2] = "g " Then
gname = Line[2..].ToLower()

''g = groups, not supportted currently
Endif

If tag[0..2] = "s " Then
Local tt:String = Line[2..].ToLower()
If tt<>"off" Then snumber = Int(Line[2..])
''s = smoothing groups, not supprted
Endif

If tag[0..7] = "mtllib " Then

If DEBUG Then Print "mtllib"

Local lib:TObjMtl[] = ParseMTLLib(Line[7..], mtllib_string)

For Local obj:TObjMtl = Eachin lib
If obj Then matlibs.Set(obj.name , obj)
Next

Endif

If tag[0..7] = "usemtl " Then

currMtl = matlibs.Get( Line[7..].Trim() )

If DEBUG Then Print "--"+Line[7..]

Local mmtrue:Int=0
Local surfnum:Int=0

If currMtl <> Null

'reuse existing surfaces
If currMtl.meshSurface
If DEBUG Then Dprint "--mtlmatch "+currMtl.name

Else
If DEBUG Then Dprint "--mtlnew "

currMtl.meshSurface = mesh.CreateSurface()

currMtl.meshSurface.PaintSurface(currMtl.brush)
If DEBUG Then Print "--use brush " + currMtl.name

SC+=1
Endif

surface = currMtl.meshSurface

If Not currMtl.cache Then currMtl.cache = New VertCache(16)

While currMtl.cache.size < VC+1
'' increase vertex index cache
currMtl.cache = New VertCache(currMtl.cache.size+16) ''wipes out old

Wend

Endif
Endif

If tag[0..2] = "f " Then

If surface = Null
''no mtl, assume only one surface, no material lib
surface = mesh.CreateSurface()
Endif
If Not currMtl Then currMtl = New TObjMtl
currMtl.meshSurface = surface

If surface

''add verts
'' avoiding index 0 as this is reserved for null

Local V:TFaceData[] = ParseFaces(Line[2..])

''assume at least 3 verts for a triangle, start at 2(base0)
'' also do not use unused verticies
'' also each surface starts at vert id =0
For Local i2:Int = 2 To V.Length() - 1

Local v0:Int = V[0].vi
Local v1:Int = V[i2-1].vi
Local v2:Int = V[i2].vi
Local t:Int =0

t = currMtl.cache.CheckVert(v0, V[0].ti, V[0].ni)

If t=0

v0 = surface.AddVertex( vertexP[v0].x , vertexP[v0].y ,-vertexP[v0].z)
'' v0+1 for real index, can't use 0
currMtl.cache.SetCache( V[0].vi, v0+1, V[0].ti, V[0].ni)

Elseif t=-1

'' different vt and vn, if so, create new vertex, **update cache
v0 = surface.AddVertex( vertexP[v0].x , vertexP[v0].y ,-vertexP[v0].z)
currMtl.cache.SetCache( V[0].vi, v0+1, V[0].ti, V[0].ni)
Else
''offset base 0
v0 = t-1

Endif

t = currMtl.cache.CheckVert(v1, V[i2-1].ti, V[i2-1].ni)
If t=0

v1 = surface.AddVertex( vertexP[v1].x , vertexP[v1].y ,-vertexP[v1].z)
'' v0+1 for real index, can't use 0
currMtl.cache.SetCache( V[i2-1].vi, v1+1, V[i2-1].ti, V[i2-1].ni)

Elseif t=-1

'' different vt and vn, if so, create new vertex, **update cache
v1 = surface.AddVertex( vertexP[v1].x , vertexP[v1].y ,-vertexP[v1].z)
currMtl.cache.SetCache( V[i2-1].vi, v1+1, V[i2-1].ti, V[i2-1].ni)
Else
''offset base 0
v1 = t-1

Endif

t = currMtl.cache.CheckVert(v2, V[i2].ti, V[i2].ni)
If t=0

v2 = surface.AddVertex( vertexP[v2].x , vertexP[v2].y ,-vertexP[v2].z)
'' v0+1 for real index, can't use 0
currMtl.cache.SetCache( V[i2].vi, v2+1, V[i2].ti, V[i2].ni)

Elseif t=-1

'' different vt and vn, if so, create new vertex, **update cache
v2 = surface.AddVertex( vertexP[v2].x , vertexP[v2].y ,-vertexP[v2].z)
currMtl.cache.SetCache( V[i2].vi, v2+1, V[i2].ti, V[i2].ni)
Else
''offset base 0
v2 = t-1

Endif


If vertexN[1] <> Null And V[0].ni <> 0
surface.VertexNormal v0 , vertexN[V[0].ni].nx , vertexN[V[0].ni].ny , vertexN[V[0].ni].nz
surface.VertexNormal v1 , vertexN[V[i2-1].ni].nx , vertexN[V[i2-1].ni].ny , vertexN[V[i2-1].ni].nz
surface.VertexNormal v2 , vertexN[V[i2].ni].nx , vertexN[V[i2].ni].ny , vertexN[V[i2].ni].nz
Endif

If vertexT[1] <> Null And V[0].ti <> 0
surface.VertexTexCoords v0 , vertexT[V[0].ti].u , 1-vertexT[V[0].ti].v
surface.VertexTexCoords v1 , vertexT[V[i2-1].ti].u , 1-vertexT[V[i2-1].ti].v
surface.VertexTexCoords v2 , vertexT[V[i2].ti].u , 1-vertexT[V[i2].ti].v
Endif

surface.AddTriangle v0, v2, v1

TRI+=1



Next

FC+=1

Endif
Endif

Endif

Wend

If DEBUG
Dprint "VertexCount : " + VC
Dprint "NormalsCount : " + VN
Dprint "TexCoordsCount : " + VT
Dprint "Faces : " + FC + " Tris : "+TRI
Dprint "Surfs : " + SC
Dprint "Surfs real : " + CountSurfaces(mesh)

For Local V:TObjMtl = Eachin matlibs.Values()
Dprint "Mtl names:"+ V.name
Next

For Local sf:TSurface = Eachin mesh.surf_list
Print "real no_verts "+sf.no_verts+" :: no_tris "+sf.no_tris
Next
Dprint "--------------------------"
Endif



'FlipMesh Mesh

stream.data = ""

''clean up buffers
For Local surfx:TSurface = Eachin mesh.surf_list
surfx.CropSurfaceBuffers()
Next

If Not hasNorms
If DEBUG Then Dprint "UpdateNormals()"
mesh.UpdateNormals() ''create norms if none
Endif

Return mesh

End
')

This should probably be added to ParseMTLLib() too.


AdamRedwoods(Posted 2014) [#159]
3DSMax .OBJ exporter actually varies the amount of spaces between the OBJ file command and params.

ok. sorry about that, that importer is from ancient code, i'll fix that part. most of it should work, since Trim() should remove most whitespace.


Sammy(Posted 2014) [#160]
NP Adam, on a related note, how is your Collada importer shaping up?

Edit: I've just notice that by the time the filename of a material gets to the ParseMTLLIB function, "map_kd ", LoadTexture() it's lost it's path too. So it won't be read in either.


AdamRedwoods(Posted 2014) [#161]
NP Adam, on a related note, how is your Collada importer shaping up?

collada took a backseat to the octree. i finally got over a major bug with it, so frustum culling works with the octree now.

LoadTexture() it's lost it's path too.

did you try my version? i thought i covered that, but i could be wrong.
https://github.com/adamredwoods/minib3d-monkey/commit/9dc46db8b1d2f6d32bf94431d9ae13608d76588d


Sammy(Posted 2014) [#162]
Really looking forward to trying your Octree culling Adam, so Im not complaining. ;)

Nope, I was just patching as I was going along, I grab it tomorrow.


AdamRedwoods(Posted 2014) [#163]
octree visualized:

this is using octrees based on volume size (the full cull sphere of a mesh). it puts the mesh in the smallest level that matches it's size. other octrees are quantity-based, which i tried, but add/delete was very slow.

the physics module i have been porting (cannonjs) can use this as well.


Sammy(Posted 2014) [#164]
Lookin good! This could make more complex open levels much more feasible on MB3D. Cannonjs should be the icing on the cake for too! :D

I've spent tonight re-coding the OBJ file importers parsing and some debugging too. Its now a lot closer to the .OBJ file format spec, also its quite a bit more robust when reading in from various .OBJ messy exporters. There is no longer a dependency for a command to be at a certain character position within the line. A line can contain any amount of spaces and also deals with TAB characters too. The parsing is now done on a per-field basis, not character. The material texture loader was not forming the correct filename, as a material can include a separate relative path. The brush textures now load in correctly as a result. A few optimisation were made to the various .GetValues methods too. A couple of other small bugs were squished. There's too many changes to list, perhaps a DIFF comparison would help.

One problem remains though, the "usemtl" command is broken, its not applying the brush correctly? I wonder if you could have a quick look Adam?(FIXED: See not below)

format_codebox('Import minib3d

Alias LoadString = app.LoadString

''--NOTES:
'' - obj does not need to be triangles, can handle polys
'' large polys (>4) may be triangulated poorly though...
'' - combines reused surfaces
'' - if vertexcache has different tex or norm index, then create a new vertex (ie. vertex with multiple tex or normal coords)

'' could try to use a flag materials to vertex colors


Class TModelObj

'#If MINIB3D_DEBUG_MODEL=1
Const DEBUG:Int =1
'#else
' Const DEBUG:Int = 0
'#Endif

Const MAXVERTS:Int = 1024 ''auto-increment as needed

Field pos:Int=0
Field data:String
Field length:Int
Field stack:StringStack = New StringStack

Global override_texflags:Int = -1
Global url_path$

Private

Method ReadLine:String()
Local s:String=""

stack.Clear()

While Not (data[pos] = 10 Or data[pos] = 13) ''~n ~r

If pos < data.Length()

If data[pos]>0
stack.Push(String.FromChar(data[pos]))
Endif

pos += 1

Else
Exit
Endif
Wend

pos += 1 ''get past the newline
If pos < data.Length()
''check for cr+lf
If (data[pos] = 10 Or data[pos] = 13) Then pos +=1
Endif

Return stack.Join("")
End


Function GetPath$(url$)

Local i:Int = url.Length()-1

If i<1 Then Return ""

While (i>-1 And (url[i] <> 47 And url[i]<>92) )
i=i-1
Wend

Return url[..i+1]

End


Public




Function LoadMesh:TMesh(url:String, flags:Int=-1)

override_texflags = flags

url_path = GetPath ( url )

Local mesh:TMesh = ParseObj(LoadString(url), flags)

If mesh = Null Then Print "**File not found "+url Elseif DEBUG Then Print"TModelObj: "+url
If mesh Then mesh.name = url
Return mesh

End

Function LoadMeshString:TMesh(data:String, mtllib:String="", flags:Int=-1)

override_texflags = flags

Local mesh:TMesh = ParseObj(data, flags, mtllib)

If mesh = Null Then Print "**Error: bad OBJ string " Elseif DEBUG Then Print"TModelObj"
If mesh Then mesh.name = "ModelOBJ"

Return mesh

End

Function ParseObj:TMesh(s:String, flags:Int=-1, mtllib_string:String = "")

Local stream:TModelObj = New TModelObj

stream.data = s
stream.length = stream.data.Length()

Local StreamLine:Int=0
If stream.length =0
Return Null
Endif

If DEBUG Then Print""

Local matlibs:StringMap<TObjMtl> = New StringMap<TObjMtl>
Local vertexP:TObjVertex[MAXVERTS]
Local vertexN:TObjNormal[MAXVERTS]
Local vertexT:TObjTexCoord[MAXVERTS]
Local faces:TFaceData[MAXVERTS]

Local gname:String = ""
Local snumber:Int = -1
Local curmtl:String = ""
Local Readface:Bool = True
Local vertsAdded:Bool = False
Local hasNorms:Int = 0

Local VC:Int = 0
Local VN:Int = 0
Local VT:Int = 0
Local FC:Int = 0
Local TRI:Int = 0
Local SC:Int = 0


Local mesh:TMesh = TMesh.CreateMesh()
Local surface:TSurface
Local surfaceCache:Int[] = New Int[255]
Local mtlCache:String[] = New String[255]
Local currMtl:TObjMtl

'mesh.name = url

While stream.pos < stream.length

Local Line:String = stream.ReadLine().Trim()

Line = Line.Replace("~t", " ")
While Line.Contains(" "); Line = Line.Replace(" ", " "); Wend
Line = Line.Trim()

If Not Line Continue

Local text:= Line.Split(" ")

Select text[0].ToUpper()

Case "#"
If DEBUG Then Dprint(".Obj Comment : " + Line)
Case "O"
mesh.name = text[1]

Case "V"
If VC>=vertexP.Length()-1 Then vertexP = vertexP.Resize(vertexP.Length()+MAXVERTS)
vertexP[VC+1] = New TObjVertex
vertexP[VC + 1].GetValues(float(text[1]), float(text[2]), float(text[3]))
VC+=1

Case "VN"
If VN>=vertexN.Length()-1 Then vertexN = vertexN.Resize(vertexN.Length()+MAXVERTS)
vertexN[VN+1] = New TObjNormal
vertexN[VN + 1].GetValues(float(text[1]), float(text[2]), float(text[3]))
VN+=1
hasNorms = 1

Case "VT"
If VT>=vertexT.Length()-1 Then vertexT = vertexT.Resize(vertexT.Length()+MAXVERTS)
vertexT[VT+1] = New TObjTexCoord
vertexT[VT + 1].GetValues(float(text[1]), float(text[2]))
VT+=1

Case "G"
gname = text[1].ToLower
''g = groups, not supportted currently

Case "S"
If text[1].ToLower <> "off" Then snumber = Int(text[1])
''s = smoothing groups, not supprted

Case "MTLLIB"

If DEBUG Then Print "mtllib = (~q" + url_path + text[1] + "~q)"

Local lib:TObjMtl[] = ParseMTLLib(url_path + text[1], mtllib_string)
For Local obj:TObjMtl = EachIn lib
If obj Then matlibs.Set(obj.name, obj)
Next

Case "USEMTL"

currMtl = matlibs.Get(text[1])

If DEBUG Then Print "--" + text[1]

Local mmtrue:Int=0
Local surfnum:Int=0

If currMtl <> Null

'reuse existing surfaces
If currMtl.meshSurface
If DEBUG Then Dprint "--mtlmatch "+currMtl.name

Else
If DEBUG Then Dprint "--mtlnew "

currMtl.meshSurface = mesh.CreateSurface()
currMtl.meshSurface.PaintSurface(currMtl.brush)
If DEBUG Then Print "--use brush " + currMtl.name

SC+=1
Endif

surface = currMtl.meshSurface
If Not currMtl.cache Then currMtl.cache = New VertCache(16)

While currMtl.cache.size < VC+1
'' increase vertex index cache
currMtl.cache = New VertCache(currMtl.cache.size+16) ''wipes out old

Wend

Endif

Case "F"

If surface = Null
''no mtl, assume only one surface, no material lib
surface = mesh.CreateSurface()
EndIf
If Not currMtl Then currMtl = New TObjMtl
currMtl.meshSurface = surface

If surface

''add verts
'' avoiding index 0 as this is reserved for null

Local V:TFaceData[] = ParseFaces(text[1 ..])

''assume at least 3 verts for a triangle, start at 2(base0)
'' also do not use unused verticies
'' also each surface starts at vert id =0
For Local i2:Int = 2 To V.Length() - 1

Local v0:Int = V[0].vi
Local v1:Int = V[i2-1].vi
Local v2:Int = V[i2].vi
Local t:Int =0

t = currMtl.cache.CheckVert(v0, V[0].ti, V[0].ni)

If t=0

v0 = surface.AddVertex( vertexP[v0].x , vertexP[v0].y ,-vertexP[v0].z)
'' v0+1 for real index, can't use 0
currMtl.cache.SetCache( V[0].vi, v0+1, V[0].ti, V[0].ni)

Elseif t=-1

'' different vt and vn, if so, create new vertex, **update cache
v0 = surface.AddVertex( vertexP[v0].x , vertexP[v0].y ,-vertexP[v0].z)
currMtl.cache.SetCache( V[0].vi, v0+1, V[0].ti, V[0].ni)
Else
''offset base 0
v0 = t-1

Endif

t = currMtl.cache.CheckVert(v1, V[i2-1].ti, V[i2-1].ni)
If t=0

v1 = surface.AddVertex( vertexP[v1].x , vertexP[v1].y ,-vertexP[v1].z)
'' v0+1 for real index, can't use 0
currMtl.cache.SetCache( V[i2-1].vi, v1+1, V[i2-1].ti, V[i2-1].ni)

Elseif t=-1

'' different vt and vn, if so, create new vertex, **update cache
v1 = surface.AddVertex( vertexP[v1].x , vertexP[v1].y ,-vertexP[v1].z)
currMtl.cache.SetCache( V[i2-1].vi, v1+1, V[i2-1].ti, V[i2-1].ni)
Else
''offset base 0
v1 = t-1

Endif

t = currMtl.cache.CheckVert(v2, V[i2].ti, V[i2].ni)
If t=0

v2 = surface.AddVertex( vertexP[v2].x , vertexP[v2].y ,-vertexP[v2].z)
'' v0+1 for real index, can't use 0
currMtl.cache.SetCache( V[i2].vi, v2+1, V[i2].ti, V[i2].ni)

Elseif t=-1

'' different vt and vn, if so, create new vertex, **update cache
v2 = surface.AddVertex( vertexP[v2].x , vertexP[v2].y ,-vertexP[v2].z)
currMtl.cache.SetCache( V[i2].vi, v2+1, V[i2].ti, V[i2].ni)
Else
''offset base 0
v2 = t-1

Endif


If vertexN[1] <> Null And V[0].ni <> 0
surface.VertexNormal v0 , vertexN[V[0].ni].nx , vertexN[V[0].ni].ny , vertexN[V[0].ni].nz
surface.VertexNormal v1 , vertexN[V[i2-1].ni].nx , vertexN[V[i2-1].ni].ny , vertexN[V[i2-1].ni].nz
surface.VertexNormal v2 , vertexN[V[i2].ni].nx , vertexN[V[i2].ni].ny , vertexN[V[i2].ni].nz
Endif

If vertexT[1] <> Null And V[0].ti <> 0
surface.VertexTexCoords v0 , vertexT[V[0].ti].u , 1-vertexT[V[0].ti].v
surface.VertexTexCoords v1 , vertexT[V[i2-1].ti].u , 1-vertexT[V[i2-1].ti].v
surface.VertexTexCoords v2 , vertexT[V[i2].ti].u , 1-vertexT[V[i2].ti].v
Endif

surface.AddTriangle v0, v2, v1

TRI+=1

Next

FC+=1

Endif

End
Wend

If DEBUG
Dprint "VertexCount : " + VC
Dprint "NormalsCount : " + VN
Dprint "TexCoordsCount : " + VT
Dprint "Faces : " + FC + " Tris : "+TRI
Dprint "Surfs : " + SC
Dprint "Surfs real : " + CountSurfaces(mesh)

For Local V:TObjMtl = Eachin matlibs.Values()
Dprint "Mtl names:"+ V.name
Next

For Local sf:TSurface = Eachin mesh.surf_list
Print "real no_verts "+sf.no_verts+" :: no_tris "+sf.no_tris
Next
Dprint "--------------------------"
Endif



'FlipMesh Mesh

stream.data = ""

''clean up buffers
For Local surfx:TSurface = Eachin mesh.surf_list
surfx.CropSurfaceBuffers()
Next

If Not hasNorms
If DEBUG Then Dprint "UpdateNormals()"
mesh.UpdateNormals() ''create norms if none
Endif

Return mesh

End


Function ParseFaces:TFaceData[] (data1:String[])


Local s:Int = 0
Local fdata:TFaceData[data1.Length() ]

For Local i:Int = 0 To data1.Length() -1 's to data1

If data1[i]="" Then Continue

fdata[s] = New TFaceData
Local D2:String[] = CustomSplit( data1[i], "/" )

'If DEBUG Then Dprint " "+D2[0] +"/ "+D2[1]+"/ "+D2[2]

If D2[0]<>"" Then fdata[s].vi = Int(D2[0])
If D2[1]<>"" Then fdata[s].ti = Int(D2[1])
If D2[2]<>"" Then fdata[s].ni = Int(D2[2])

If fdata[s].vi <0 Then fdata[s].vi=0
If fdata[s].ti <0 Then fdata[s].ti=0
If fdata[s].ni <0 Then fdata[s].ni=0

s+=1

Next

fdata = fdata.Resize(s)

Return fdata

End

Function CustomSplit:String[](st:String, delim:String)

''handles n/n/n as 3 numbers even when n//n
Local out:String[] = New String[3]

If st.Length() < 1 Then Return [""]

Local n:Int=0, nn:Int=0
Local reset:Int=1
Local s:String

For Local i:Int = 0 To st.Length() -1
If reset
out[n] = "0"
reset = 0
Endif
If st[i] = delim[0]
Local ii:Int = i+nn
s = st[i..ii]
'out[n] = s

n+=1
reset=1
nn=0

Else
out[n] += String.FromChar(st[i])
nn+=1
Endif
Next
'Print nn
Return out

End


Function ParseMTLLib:TObjMtl[](url:String, mtllib_string:String)

Local MatLib:TObjMtl[0]
Local stream:TModelObj = New TModelObj

stream.data = LoadString(url)

''see if we have a string
If Not stream.data And mtllib_string Then stream.data = mtllib_string

If Not stream.data
stream.data = LoadString(url+".txt")

If Not stream.data

Print "**TModelObj: Material obj file not found: " + url
Return MatLib
Endif
Endif

stream.length = stream.data.Length()

Local CMI:Int = -1
Local is_brush:Int =0

While stream.pos < stream.length

Local Line:String = stream.ReadLine()

Line = Line.Replace("~t", " ")
While Line.Contains(" "); Line = Line.Replace(" ", " "); Wend
Line = Line.Trim()

If Not Line Continue

Local text:= Line.Split(" ")

Select text[0].ToUpper()

'Remark
Case "#"

'Create new brush
Case "NEWMTL"
MatLib = MatLib.Resize(MatLib.Length() +1)
CMI = MatLib.Length() -1

MatLib[CMI] = New TObjMtl
MatLib[CMI].name = text[1]
MatLib[CMI].brush = CreateBrush()
MatLib[CMI].brush.BrushFX 0 ''default, used to be 4+16
MatLib[CMI].brush.name = MatLib[CMI].name
is_brush = 1

If DEBUG Then Dprint("Matname : " + MatLib[CMI].name)

'Colours
Case "KD"
If is_brush
MatLib[CMI].brush.BrushColorFloat(float(text[1]), float(text[2]), float(text[3]))
If DEBUG Then Dprint("MatColor : " + (float(text[1]) * 255) + "," + (float(text[2]) * 255) + "," + (float(text[3]) * 255))
Endif

Case "D"
If is_brush
MatLib[CMI].brush.BrushAlpha(Float(text[1]))
If DEBUG Then Dprint("MatAlpha ~qD~q: " + Float(text[1]))
EndIf

Case "TR"
If is_brush
MatLib[CMI].brush.BrushAlpha(Float(text[1]))
If DEBUG Then Dprint("MatAlpha ~qTR~q: " + Float(text[1]))
EndIf

Case "MAP_KD"
If is_brush

' Still needed?
' Local texfile:String[] = Line.Split("\") ''blender fix
' If texfile.Length() < 2 Then texfile = Line.Split("/") ''blender fix
' texfile[0] = texfile[texfile.Length()-1] ''get rid of any prior folders (blender fix)

'note: Map_kd files can have a full relative path, so stripping off to the filename, as above,
' removes sub-folder allocation, this is why I use the full map_kd path here.
' Absolute paths are not used by monkey, so the user needs
' to ensure any paths here are relative to url_path, a map_kd of "maps/texture.png" for example can become
' "monkey://data/obj/maps/texture.png" for example(url_path was "monkey://data/obj/")

'[7..] to include paths with spaces.
Local mapFile:String = url_path + Line[7 ..].Replace("\", "/")
Local flags:Int = TTexture.default_texflags
If override_texflags > - 1 Then flags = override_texflags

If DEBUG Then Dprint("LOADTexture : " + mapFile)
MatLib[CMI].texture = LoadTexture(mapFile, flags)

If MatLib[CMI].texture.TextureHeight() > 1
MatLib[CMI].brush.BrushTexture(MatLib[CMI].texture)
If DEBUG Then Dprint("MatTexture : " + mapFile)
Else
If DEBUG Then Print "**TModelObj: ~q" + mapFile + "~q texture file not found"
Endif
Endif
End
Wend

Return MatLib
End

End


Class TFaceData

Field vi:Int
Field ti:Int
Field ni:Int
Field its:Int

End




Class TObjNormal
Field nx# , ny# , nz#

Method GetValues(f0:Float, f1:Float, f2:Float)
nx = f0; ny = f1; nz = f2
End Method
End

Class TObjTexCoord
Field u# , v#

Method GetValues(f0:Float, f1:Float)
u = f0; v = f1
End Method

End

Class TObjVertex
Field x# , y# , z#

Method GetValues(f0:Float, f1:Float, f2:Float)
x = f0; y = f1; z = f2
End Method
End

Class TObjMtl

Field name:String
Field brush:TBrush
Field texture:TTexture

Field meshSurface:TSurface

Field cache:VertCache

Method New()
cache = New VertCache(1)
End
End

Class VertCache

Field size:Int =1
Field realvertindex:Int[1] ''cache vert address when created
Field texusedindex:Int[1] ''cache vert to tex coord index
Field normusedindex:Int[1] ''cache vert to normal index used

Method New( i:Int )
realvertindex = New Int[i]
texusedindex = New Int[i]
normusedindex = New Int[i]
size = i
End

'' CheckVert(vert index, texture index, norm index)
Method CheckVert:Int( i:Int, ti:Int, ni:Int)

If i>size-1 Then Return 0

If Not realvertindex[i] Then Return 0

''-- check for similar vertex, different vt and vn, if so, create new vertex

If (texusedindex[i] <> ti And ti<>0) Return -1
If (normusedindex[i] <> ni And ni<>0) Return -1

''else return real vertex index
Return realvertindex[i]

End

Method SetCache(i:Int, reali:Int, ti:Int=0, ni:Int=0)
''set real vert index

If i>size-1
realvertindex = realvertindex.Resize(i+1)
texusedindex = texusedindex.Resize(i+1)
normusedindex = normusedindex.Resize(i+1)
size = i+1
Endif

realvertindex[i] = reali
texusedindex[i] = ti
normusedindex[i] = ni
End

End')
Updated Comments "#" Parse
Fixed paths in MTL file for paths with spaces

To load a .OBJ file in you need to override the default TTexture flags, as they are set to 1+8. Basically if you dont set the texture flags to have 2(Alpha in texture) in it, you dont see any textures(like alpha is set to 0.0?) or mesh when you load in a texture to a brush with the default flags(1+8). Strangely this only happens if you try and load a .OBJ into a TMesh but if you load it into an TEntity, all is well?!?

So, setting your LoadMesh to LoadMesh("filename.obj",, 2 + 8) reads in the .OBJ file properly. It now handles a lot more .OBJ files.


EdzUp(Posted 2014) [#165]
Sorry for the late reply adam is freeing surfaces done via Object.FreeSurface( index ) or is there a free surface( Object, index ) command?


AdamRedwoods(Posted 2014) [#166]
mesh.GetSurface(index).FreeSurface()


Sammy(Posted 2014) [#167]
BUG: CopyMesh() does not seem to copy the surfaces of the source mesh ("mesh.surf_list = new_list", maybe "mesh.surf_list = self.surf_list"?), copy a mesh and you loose surfaces.

I found why I had trouble with textures BTW.

Can you test the .OBJ importer above Adam, I think it should handle a lot more .OBJ+.MTL files now.


slenkar(Posted 2014) [#168]
I used the matrix and vector class to rotate an image in 3 dimensions. It's been very useful so thanks for the code!


AdamRedwoods(Posted 2014) [#169]
It's been very useful so thanks for the code!

cool, you're welcome!

Can you test the .OBJ importer above Adam, I think it should handle a lot more .OBJ+.MTL files now.

very nicely done! thanks. much more readable, too. i'll add it in.

one minor bug, there was an infinite lock on the first line of this section. this is what i think you meant: EDIT: lol, ok, backslashes don't show up in the code box. need double-backslashes
format_code('
Local mapFile:String = url_path + Line[7 ..].Replace("\\", "/")
Local flags:Int = TTexture.default_texflags
If override_texflags > - 1 Then flags = override_texflags

If DEBUG Then Dprint("LOADTexture : " + mapFile)
')

..
re: CopyMesh()
the reason i did that was because CopyBaseMeshTo() overwrites the mesh.surf_list, so i had to write it back. AddMesh() creates new surfaces, so we don't want to use Self.surf_list.
i wonder if there's something wrong with the AddMesh().
my simple example worked ok here, do you have an example?


Sammy(Posted 2014) [#170]
Yikes! I'll have to remember that when posting anything a backslash in it. Thanks for that.

I used CopyMesh() to copy a static mesh, the resulting mesh had no textures. I examined the copied mesh and the surface list was Null. I temporarily added the patch that I mentioned above and the textures appeared with the same example. Since this is a full non-pointer only copy, maybe loop through the surfaces and create a new list of copied surfaces instead for CopyMesh()?

Sorry, it's difficult for me to provide an example as copying meshes, in this instance, is done via my scripting language.


AdamRedwoods(Posted 2014) [#171]
Since this is a full non-pointer only copy, maybe loop through the surfaces and create a new list of copied surfaces instead for CopyMesh()

that is what AddMesh() is doing. need to find out why that isn't working for your specific instance.


Sammy(Posted 2014) [#172]
I'll try and whip up a small test program with a model and post it to you Adam. This will probably be sometime tomorrow.

I'll update my install from the Git repo too, just in case.


Sammy(Posted 2014) [#173]
A quick function to extract the used textures filenames for pre-loading before using an .OBJ.

format_code('
Function GetTexts:String[] (filename:String)
Local files:StringStack = New StringStack
filename = filename.Replace("\\", "/")
Local path:String = filename[ .. filename.FindLast("/") + 1]
filename = filename[filename.FindLast("/") + 1 ..]
#If DEBUG=1
Print "GetTexts(~q" + path + filename + "~q)"
#Endif
For Local line:= EachIn mojo.LoadString(path + filename).Split("~n")
'Remove Quotes & Tabs & Extra spaces
line = line.Replace("~q", "").Replace("~t", " ")
While line.Contains(" "); line = line.Replace(" ", " "); Wend
line = line.Trim()
'Remarks
If Not line Or line.StartsWith("#") Continue
Local bits:= line.Split(" ")
Select bits[0].ToUpper()
Case "MTLLIB"
#If DEBUG=1
Print " MTLLIB = ~q" + path + bits[1] + "~q"
#Endif
For Local lineMtl:= EachIn mojo.LoadString(path + bits[1]).Split("~n")
'Remove Quotes & Tabs & Extra spaces
lineMtl = lineMtl.Replace("~q", "").Replace("~t", " ")
While lineMtl.Contains(" "); lineMtl = lineMtl.Replace(" ", " "); Wend
lineMtl = lineMtl.Trim()
'Remarks
If Not lineMtl Or lineMtl.StartsWith("#") Continue
Local bitsMtl:= lineMtl.Split(" ")
Select bitsMtl[0].ToUpper()
Case "MAP_KD"
Local filenameMtl:= lineMtl[7 ..].Replace("\\", "/")
#If DEBUG=1
Print " MATERIAL =~q" + path + filenameMtl + "~q"
#Endif
files.Push path + filenameMtl
End
End
End
End
Return files.ToArray
End Function
')

I posted that CopyMesh() bug example to your email address BTW too Adam.


EdzUp(Posted 2014) [#174]
How do you count the surfaces in a mesh I have tried Entity.CountSurface() and CountSurfaces( Entity ) but I get an error saying there is no overload for that function. What is the correct way to run through the surfaces and free them.


consty(Posted 2014) [#175]
Just download this project from github.
How can you install it as a module?


Sammy(Posted 2014) [#176]
@Ed, CountSurfaces() is only available to TMesh, you can cast your Entity to a mesh temporary with "Local SurfCnt:=CountSurfaces(TMesh(Entity))"
Clearing it, um, something like... "TMesh(Entity).surf_list.Clear"

I must say though, I've not used these commands or know if this is the 'official' MB3D way of doing things. :P But it may get you past your impass till Adam gets back to you.

@const:

Copy the contents of your Git archive into your installed "modules" modules folder(It's next to where Monkey.exe is located), do not extract to the GitHub folder("minib3d-master" or whatever its called, only miniB3D) name.

Mines looks like "C:\Coding Folder\Middleware\Monkey Pro\modules\minib3d\"
Where "C:\Coding Folder\Middleware\Monkey Pro\" is where I've installed Monkey
and "C:\Coding Folder\Middleware\Monkey Pro\modules\" is where I put new modules.
and "C:\Coding Folder\Middleware\Monkey Pro\modules\minib3d\" is where I unpack the MiniB3D Git archive into. There should be plenty of .monkey files in here, BTW if you installed it correctly.

Add "import minib3d" to the top of your listing and your good to go.

Edit: Grrr, I had this all tabulated with spaces but the website seems to have removed this simple formatting.


AdamRedwoods(Posted 2014) [#177]
@Ed, CountSurfaces() is only available to TMesh, you can cast your Entity to a mesh temporary with "Local SurfCnt:=CountSurfaces(TMesh(Entity))"

yes, an Entity does not have surfaces, only meshes. So a cast would be needed TMesh(myEntity).CountSurfaces().


EdzUp(Posted 2014) [#178]
Ah ok will have a look maybe adding a count surface command to entity would be in order iirc minib3d on max allowed it:)


AdamRedwoods(Posted 2014) [#179]
ok, easy enough to do (slated for v0.43) TEntity.monkey:
format_code('
Method CountSurfaces:int()
Return 0
End
')

Re:Sammy Obj texture preloader
A quick function to extract the used textures filenames for pre-loading before using an .OBJ.

this is interesting, because a question would be: is it up the coder to PreLoad() all of their textures, including ones assigned to the models, or do we automatically load them? i guess we can auto-preload them since the loaders will be looking for them anyways. i should make note of this for B3D and collada.


EdzUp(Posted 2014) [#180]
Adding the casting from TEntity to TMesh seems to yeild VC++ COFF program crashing here on Windows. I get a "COFF has stopped responding" error and Vista closes it down. Removing the casting (remarking the lines out) the program compiles correctly.

What im doing is:
format_code('
Function EdzUpFreeEntity( Mesh:TEntity )
Local EFE:Int

For EFE =0 To TMesh( Mesh ).CountSurfaces( )
TMesh( Mesh ).GetSurface( EFE ).FreeSurface()
Next
End
')


Sammy(Posted 2014) [#181]
I think that should be "For EFE = 0 Until TMesh("... not sure if your function above is going to cover you for child entities though Ed.

@Adam: Ideally yes, pre loading of textures should automatic, also, I'm not really happy with parsing a model file twice, once for preloading the textures, then again later for the vertices etc. I suppose the OBJ file importer could do both at once though with a little alteration that is and then call the OBJ importing before the texture preload call has been executed. Resulting in the mesh data structure and also an array of texture file names.

I will have to use the manual method for now though as I'm pushed for time on this section of my code by my GFX guy.

TBH I dislike the current preload methodology, logically it still feels like you loading a texture twice even though your not, also there is no exposed API call to check if a specific texture is actually in memory. It's wait for all or nothing AFAK. I would prefer that you are able to load a texture in from LoadTexture as normal, it is then queued asynchronously to be loaded. Each texture could have a "hasLoaded" bool which can be checked by the coder to say if it's safe to use. Having the option to wait for an essential texture before continuing would then be up to the coder. This is just a suggestion though.


consty(Posted 2014) [#182]
Thanks Sammy, it worked. :)


Sammy(Posted 2014) [#183]
Your welcome Const. :)


AdamRedwoods(Posted 2014) [#184]
I would prefer that you are able to load a texture in from LoadTexture as normal, it is then queued asynchronously to be loaded. Each texture could have a "hasLoaded" bool which can be checked by the coder to say if it's safe to use. Having the option to wait for an essential texture before continuing would then be up to the coder. This is just a suggestion though.

the problem i ran into with that idea, was that on flash and html5, someone may try to modify a texture (GetPixel) before it's done loading on asynchronous targets, and i cannot lock program execution. the best i can think of right now, is to add GetTexture("filename")/GetPixmap("filename") and that would return null if not done loading or the object once loaded... perhaps this way the API may make more sense.

Another thought is that EVERY loader could be asynchronous, and throw an assertion error if data to a texture or model is accessed before it is done loading. may take more time to implement.

There is a TPixmap.IsLoaded("filename") bool.


EdzUp(Posted 2014) [#185]
Thanks Sammy will try that :)

EDIT:Well it compiles not but I still have the same memory issues that I had in the beginning.


AdamRedwoods(Posted 2014) [#186]
Octree update: This is the best I can do with 2000 objects floating around. use the WASD keys to move around, arrow keys to rotate around. press 1 and 2 to switch between rendering via list or via octree.
The difference is minimal, but the octree is much slower on android. Should also keep in mind for this simple example, there is no texture switching, and the vertex buffers are mostly the same. The octree could also be useful for object occlusion if I can think of a way, but for now it's used for rendering and soon collisions.

http://www.twopisoftware.com/monkeycoder/octree/test.html
(this link will be taken down after a couple weeks)

i'm using loose octrees, btw:
http://tog.acm.org/resources/RTNews/html/rtnv14n1.html#art4


AdamRedwoods(Posted 2014) [#187]
EDIT:Well it compiles not but I still have the same memory issues that I had in the beginning.

are you freeing the mesh after the surfaces?
format_code('
Function EdzUpFreeEntity( Mesh:TEntity )
Local EFE:Int

For EFE =0 To TMesh( Mesh ).CountSurfaces( )
TMesh( Mesh ).GetSurface( EFE ).FreeSurface()
Next
Mesh.FreeEntity()
End
')
if so, you can try to run your program on HTML5 target on chrome, and do control-shft-j and do a profile for the heap to see what's taking up all the memory.


EdzUp(Posted 2014) [#188]
I think when i replaced the freeentity command i forgot to add it to my function Doh!!

my game doesn't like HTML5 though which is a shame as it would be a brilliant platform to demo on :)

for what its worth my game when coded using Unity also crashes the webplayer lol. Must be all the procedurally generated textures :)


EdzUp(Posted 2014) [#189]
Right with the free entity in there I can hyperspace 7 times before it out of memory errors.

@adam: is there any of the other Free... Commands that aren't actually in there, I'm using FreeTexture etc. With commands like LoadSprite will FreeEntity kill of the loaded texture as well or does that have to be got rid of manually and if so how can we go about it?


Sammy(Posted 2014) [#190]
@Adam: The difference for me is minimal too (5-6ms on Octree, 6-12ms on Windows HMTL 5). I did like how the Octree seemed to have a pretty steady ms count though, as opposed to the master list that was all over the place. It should be easier to control lag spikes with the Octree in place.

Over all though very impressive Adam, well done! :)

the problem i ran into with that idea, was that on flash and html5, someone may try to modify a texture (GetPixel) before it's done loading on asynchronous targets, and i cannot lock program execution. the best i can think of right now, is to add GetTexture("filename")/GetPixmap("filename") and that would return null if not done loading or the object once loaded... perhaps this way the API may make more sense.

Another thought is that EVERY loader could be asynchronous, and throw an assertion error if data to a texture or model is accessed before it is done loading. may take more time to implement.

There is a TPixmap.IsLoaded("filename") bool.

All of the above options give me more control Adam so I would be happy with any of these additions TBH.


Sammy(Posted 2014) [#191]
I was considering using multi-texturing for some simple level decals but I realise some platforms have problems with this but I can't find the post(the new forum search is pretty bad), what are the things I have to be aware of? Is there a better method for decals in general?


AdamRedwoods(Posted 2014) [#192]
I was considering using multi-texturing for some simple level decals but I realise some platforms have problems

AFAIK, the only problem was: XNA = 1 texture, opengl2.0, flash, html5 = 4 textures. i can increase the opengl2.0 if it's needed, i could create an on-demand compilation for >4 textures.

OFF-TOPIC:
updated a bug when using CopyEntity() for meshes with bones. (github)


Sammy(Posted 2014) [#193]
Ah, thanks for that Adam, that's quite surprising that XNA can only handle 1 texture. 4 should be fine for me otherwise, it's mainly for single items, like signs for example.

Also, thanks for the CopyEntity() fix, I'll take a peek after a post this thread.


Dip(Posted 2014) [#194]
I've just started playing with minib3d, coming from a blitz3d then blitzmax background. I'm excited to start putting it in my game that was previously using a software 3d renderer, but I'm running into a roadblock. I have some 2d screens (menu, help, etc) that I want to be able to display after I switch to '3d mode' and I can't seem to figure out how to make it work. I'm not talking about a 2d overlay on top of the 3d scene, as I know that could be complicated under the hood. I just want to be able to 'switch out' of 3d entirely and use regular mojo commands if the game is in certain states.

I've tried to mimic the examples but I either get a black screen for the whole game, or I get my scene bouncing back and forth between two frames (I just have a simple rotating cube on the screen for starters). I've tried SetMojoEmulation() but it doesn't seem to have any effect. Is there an example out there that can do this, or am I asking something not possible yet?

I saw this code here http://monkeycoder.co.nz/Community/posts.php?topic=4421 which looks like even more than what I want right now, but the version of minib3d is 0.33.x and with the current version being 0.42.x I don't want to lose the extra functionality and bug fixes in the interim. I tried just using the util folder from 0.33 and copying it into the latest but that ran into some 'method/function not found' errors.


Sammy(Posted 2014) [#195]
SetMojoEmulation() at the start of my OnRender%() works fine for me? I'm just using the normal 2D mojo commands after this point to draw 2D stuff on top of the 3D context. Can you whip up a quick example of the problems you are having? If your testing on HTML5, you may be forgetting to preload ( PreLoadPixmap() ) your 2D images as well as your 3D textures, this would give you a blank screen.


Dip(Posted 2014) [#196]
Thanks for the reply. That's what it seemed to be from everything that I could find, but it just didn't work for me in practice and I'm not sure why. I'm using Gflw for now, and when I compile it shows "miniB3D opengl11" if that makes a difference. Here's a skeleton version of my game just to show the issue I'm having:
format_code('
Import mojo
Import minib3d

Global gameState
Global menuState
Global configState
Global displayState
Global maxResources
Global numResources

Const COPY_TO_PROJECT_DATA_FOLDER:Bool=True
Const STATE_LOADING = 1
Const STATE_LOADCONFIGS = 2
Const STATE_MENU = 3
Const STATE_PREGAME = 4
Const STATE_LOGIN = 5
Const STATE_PROCESSLOGIN = 6
Const STATE_PROCESSMENU = 7
Const STATE_PLAY = 8
Const STATE_NEWCHAR = 9
Const STATE_PROCESSNEW = 10
Const STATE_ENTERPASS = 11
Const STATE_PROCESSPASS = 12
Const DISPLAY_FPS = 1
Const DISPLAY_TILEPICKER = 2
Const DISPLAY_MAP = 3
Const DISPLAY_HELP = 4
Const MENU_MAIN = 1
Const MENU_CONFIG = 2

Class MyTest Extends App
Field Camera:TCamera
Field Light:TLight
Field Cube:TMesh
Field started3D:Bool

' Stuff to do on startup...
Method OnCreate()
InitGame()
SetUpdateRate 10
End

' Stuff to do while running...
Method OnUpdate()
UpdateAsyncEvents()
If gameState = STATE_LOADING
Else
HandlePlayerKeys()
If gameState = STATE_PLAY
If displayState = DISPLAY_FPS Then Update3D()
Endif
Endif
End

Method OnLoading()
Cls 0,0,0
DrawText("Initializing... ",120,420)
End

' Drawing code...
Method OnRender()
If started3D Then SetMojoEmulation()
Select gameState
Case STATE_LOADING
Cls 0,0,0
DrawText("Loading... ",120,420)
Case STATE_PLAY
Select displayState
Case DISPLAY_FPS RenderFirstPerson3D()
Case DISPLAY_HELP RenderHelp()
End
End
End

Method InitGame()
gameState = STATE_PLAY
menuState = MENU_MAIN
displayState = DISPLAY_FPS
End

Method HandlePlayerKeys()
Select gameState
Case STATE_PLAY
If displayState = DISPLAY_HELP
HandleHelpKeys()
Else
HandleFirstPersonKeys()
Endif
End
End

Method HandleFirstPersonKeys()
If KeyHit(KEY_F1) Then displayState = DISPLAY_HELP
End

Method HandleHelpKeys()
If KeyHit(KEY_ESCAPE) Then displayState = DISPLAY_FPS
End

Method Init3D()
' Normally all game elements are invoked in the OnCreate() method, but with Minib3D you
' can do this only when the app call for the first time the OnRender() method.
SetRender()
Camera = CreateCamera()
Camera.CameraClsColor(0,0,80)
Light=CreateLight(1)
Light.MoveEntity -10,10,10
Light.TurnEntity 35,-40,0
Cube=CreateCube()
Cube.PositionEntity -0.5,-2.5,8
started3D = True
End

Method Update3D()
' do things like modify lighting and move entities to match object positions
If started3D
Cube.TurnEntity 0,1,0
UpdateWorld()
Endif
End

Method RenderFirstPerson3D()
If Not started3D
Init3D()
Else
RenderWorld()
Endif
End

Method RenderHelp()
DrawText("Help",400,20)
DrawText("Press Esc to exit this help",400,580)
End
End

Function Main ()
New MyTest
End
')

If I run the above, I get the spinning cube on the screen. If I hit F1 to display help, I get the cube still on the screen, but toggling back and forth between two states (I assume since updateworld isn't called).


Sammy(Posted 2014) [#197]
Change to this...

format_code('
Method RenderHelp()
DrawText("Help",400,20)
DrawText("Press Esc to exit this help", 400, 180)
RenderWorld()
End
')

You need a RenderWord() to cause a page 'flip', to see your text, even when using 2D text in after a SetMojoEmulation() call. I changed the Y component of your second text line to 180, as the text was outside the bottom of the window BTW.


Dip(Posted 2014) [#198]
It was that easy, thanks. Yeah the code was a quick delete of my game code and I didn't take into consideration window size changes. I thought I tried with the RenderWorld() afterwards and it didn't work, must've been a factor of late night and trying too many different things. It's working now, thanks for the helpful and timely response!


Sammy(Posted 2014) [#199]
NP ;)


Deen(Posted 2014) [#200]
hi Adam,

i am still with the same issue last time - lighting.. thought chrome's webGL issue but it is actually not.. today i'm trying back all of the tutorial files ive made with monkey 77a (demo) + minib3d_0.42 + firefox browser and compile it for html5.. the light is not appearing, unless i set all mesh with entityfx 1, then everything is shown with full bright (light is ignored). but when i revert back to monkey77a + minib3d_0.37 + firefox, every light setup is shown correctly. so i reckon, the lighting issue is coming at latest update of minib3d.. has anyone else facing the same issue as mine?

forgot to mention that everything is working fine when i compile it to Desktop GLFW (whatever version of minib3d will work just fine in here)


julesd(Posted 2014) [#201]
Just wondering, are all the commands at this post the proper command.
Also if they are, are all of the commands implemented, and are there other commands not listed there?

http://blitzmax.com/b3ddocs/command_list_3d_cat.php


AdamRedwoods(Posted 2014) [#202]
Just wondering, are all the commands at this post the proper command.

most of them are implemented. but in addition for miniB3D, most are object-oriented.
I have not implemented TTerrain yet.

and are there other commands not listed there?

hundreds. classes like TShader and Framebuffer and LoadObjMesh, UseMojoEmulation, BoneToVertexAnim, ActivateBones, CreateGrid, CreateBatchSprite, CreateText3D, SetNormalMapping, CollisionSetup, CameraLayer, PositionToVertex, and OO shortcuts like Position, Scale, Rotate (without the Entity word).
Docs are coming, slowly.


AdamRedwoods(Posted 2014) [#203]
when i revert back to monkey77a + minib3d_0.37 + firefox, every light setup is shown correctly

well, the HTML5 target uses shaders, which is limited to one light at the moment. i have not created the deferred (or light-indexed) shader yet to support many lights.

the desktop target uses opengl es1.1, which supports 8 lights because of the fixed-function pipeline.

with the current shader, it would take a little work to add more lights. how badly do you need it and how many lights do you need? I think i can make an on-demand shader to allow more lights.


Deen(Posted 2014) [#204]
i see, that shed me some lights on this.. anyway, actually i just need one light (directional) is good enough. even i only setup only one light in the scene, it still not appearing anything. anyway thanks Adam, im not need it badly since my target compiled is for Android, only that i like to 'quickly see' the result in html5 first before i port to targeted device (you know how fast it compile for html5).

another question, b3d mesh cant load multitexture (multi-UV)? my diffuse is on UV1 (texture slot 1), my lightmap is on UV2 (texture slot 2).. is that possible? xtra infomation, my b3d mesh directly exported from 3dsmax 8 pipeline V0.8 (not gile[s])..

and all my b3d mesh have to load the textures manually one by one? (not automatically loaded like the way it did before?)


AdamRedwoods(Posted 2014) [#205]
even i only setup only one light in the scene, it still not appearing anything

that is strange. i wonder if the normals on the model are wrong? try using " mesh.UpdateNormals() " after loading the model.
another thing is check the html5 target in debug mode and see if any shader errors are appearing.

b3d mesh cant load multitexture (multi-UV)?

it should.
if you enable "#MINIB3D_DEBUG_MODEL=1" at the beginning of your file, the compiler will add debug info when loading the B3D mesh, and it should output what UV coords the mesh is using.

and all my b3d mesh have to load the textures manually one by one?

for html5 and flash, you must PreLoad() all textures, even those in model files. this is because these targets use only asynchronous loaders. you don't need to do this for desktop targets. i am thinking of how to make this easier by perhaps incorporating PreLoad for models as well.

for now, you can use arrays to make it easier:
format_code('
Field myFileArray:String[] = ["Zombie.jpg","mojo_font.png","wabbit_alpha.png"]

Method OnCreate()
TPixmap.PreLoadPixmap(myFileArray)
End

Method OnUpdate()
TPixmap.PreLoadPixmap() ''updates the loader
If (TPixmap.GetNumberLoaded() = myFileArray.Length()) doneLoadingFlag = true
If not doneLoadingFlag then return ''or show wait screen
End
')


Soap(Posted 2014) [#206]
Curious if anyone is making a full game with this Monkey version yet?


EdzUp(Posted 2014) [#207]
Yup making Star Rogue in it but I'm working through issues with me code atm


Soap(Posted 2014) [#208]
I look forward to seeing any progress you want to share! I really want to make some simple low poly PS1 era style games.


EdzUp(Posted 2014) [#209]
Have a look at the project post on this forum :)


Sammy(Posted 2014) [#210]
I'm making a full game with miniB3D+Monkey too. Not a great way into the project yet though.

and are there other commands not listed there?

hundreds. classes like TShader and Framebuffer and LoadObjMesh, UseMojoEmulation, BoneToVertexAnim, ActivateBones, CreateGrid, CreateBatchSprite, CreateText3D, SetNormalMapping, CollisionSetup, CameraLayer, PositionToVertex, and OO shortcuts like Position, Scale, Rotate (without the Entity word).
Docs are coming, slowly.


Adam is there a way you could rustle up a full list of these commands? It would be handy to know what extras are available to your port.


Deen(Posted 2014) [#211]
Hi Adam,

so weird, it wont happen that way on my system... i have to do this instead to show my texture properly diffused on my mesh

format_code('
Method OnCreate()
'don't have to preload anything here, wont help anything here
End

Method OnUpdate()
If Not TPixmap.PreLoadPixmap(["pack_sachet_lm.png"]) Then Return
'here also i dont have to preload anything - in fact i dont need TPixmap.PreLoadPixmap() command at all in my apps

'but i have to do this instead
Local texture:TTexture = LoadTexture("pack_sachet_lm.png")

Monkey1 = LoadMesh("pack_sachet.b3d")
'and i dont have to manually EntityTexture it. just LoadTexture command above would be sufficient
End
')
then only my textured mesh visible on the screen...

when im on debug mode (html5) + minib3d_debug_model = true, i've got this printed out:


WebGL 1.0
..WEBGL 1
..FullShader success
..FastBrightShader success
..loading B3DBinary:monkey://data/pack_sachet.b3d
TModel
TEXS
-Load Texture:0 pack_sachet_lm.png blend:2 coords:1
BRUS
brush:0 tex:0
brush:0 tex:-1
brush:0 tex:-1
brush:0 tex:-1
brush:0 tex:-1
brush:0 tex:-1
brush:0 tex:-1
brush:0 tex:-1
brush:0 rgb:1 1 1 blend:1 fx:0 no_texs:8
NODE
- NODE (parent= Scene Root)
- MESH
- VRTS
no_verts:2375
- TRIS
painting ent:-1 surf:0
no_tris:1665 no_verts2374




AdamRedwoods(Posted 2014) [#212]
b3d mesh cant load multitexture (multi-UV)?

possible bug. the flags may be becoming less than -255, which triggers a texture delete in the binding queue.
try putting this change at line 371 in the file "tmodelb3d.monkey":
format_code('
te_flags=te_flags& $0ffff
')
if not, it may be a shader/render bug somewhere, that doesn't like uv-1 being the only coord set.


MikeHart(Posted 2014) [#213]
So what is the secret to build a project with monkey78b and the latest minib3d on HTML5? I am always getting

format_code('C:/MonkeyXPro78b/modules/os/os.monkey<14> : Error : Native OS Module not implemented')

when I build the examples that are shipped with minib3d.


AdamRedwoods(Posted 2014) [#214]
So what is the secret to build a project with monkey78b and the latest minib3d on HTML5? I am always getting

Bug! thanks.
in the file "monkeyutility.monkey" change "Import os" to:
format_code('
Import gametarget
')


MikeHart(Posted 2014) [#215]
Thanks for responding quickly.


Deen(Posted 2014) [#216]
Adam,

can you create a noise method in grid mesh... i just wondered when you allowed to create grid with some amount of segments (for whatever reason), so then with grid.Noise(height:Float) letsay, will actually noise the grid to be looks like smooth little terrain (and can be expand into animated noise height which will help in simulating a water surface effect when the terrain engine complete later)


AdamRedwoods(Posted 2014) [#217]
can you create a noise method in grid mesh

format_code('
Function JitterMesh:Void( mesh:TMesh, heightx:Float, heighty:Float, heightz:Float )
local v:Vector = New Vector
For local ss:TSurface = Eachin mesh.surf_list
For local i%=0 to ss.no_verts-1
local x:float = Rnd()*heightx
local y:float = Rnd()*heighty
local z:float = Rnd()*heightz
ss.GetVertexCoords(i,v)
ss.VertexCoords(i,v.x+x,v.y+y,-(v.z+z))
Next
Next
End
')
probably too slow for water, but if you precache the sine waves in an array, that could be used for about 1000 vertices.

EDIT:
Adam is there a way you could rustle up a full list of these commands? It would be handy to know what extras are available to your port.

look at NOTES.txt, i try and list all changes per version.

EDIT:
Updated jitter to not flip mesh, added to v0.43.


AdamRedwoods(Posted 2014) [#218]
level-of-detail (LOD) and octree. you can see the areas of LOD changes, the second level has textures removed, the third is just sprites.
1000 zombies, animated. the sprites don't animate. (webgl)
coming soon, in v0.43



Sammy(Posted 2014) [#219]
Nice! :)


EdzUp(Posted 2014) [#220]
Nice :)

What are the commands behind it or is it automatic?


Sammy(Posted 2014) [#221]
Yes, could be handy for anything that requires lots of scene meshes, crowd scenes, foliage engine, asteroid fields(Ed? ;)) etc.

Preferably it should be optional though and not hardcoded into the engine by default IMHO.


EdzUp(Posted 2014) [#222]
Personally I think it should with a enable/disable switch and a mesh option to be ignored from the system :)


AdamRedwoods(Posted 2014) [#223]
What are the commands behind it or is it automatic?

mesh.SetLOD(level:int, distance:Float, lod_mesh:TMesh)
level = 1-3, could be used with only 1 level

example:
format_code('
Local simplezombie2:TMesh = TMesh(zombie[0].CopyMesh())
Local zbrush:TBrush = New TBrush(55,55,55)
simplezombie2.PaintMesh(zbrush) ''get rid of texture
'simplezombie2.DisableAnim() ''optional
zombie[0].SetLOD(1, 50.0, simplezombie2)
')


Deen(Posted 2014) [#224]
can we expect to see 'physics' implement in miniB3D + Monkey X later? any wrapper from b3d time can be brought in?


AdamRedwoods(Posted 2014) [#225]
can we expect to see 'physics' implement in miniB3D + Monkey X later?

yes, i have ported most of CannonJS, but have not had time to get it to work yet.


Sammy(Posted 2014) [#226]
The seems to be a small bug with CopyEntity() or maybe its the way its designed? It looks as if the copied entity does not use the current copied entities transformation matrix but relies on the parent entities one only for transformations, dropping the copied entities current one before each transformation command?

So...
format_codebox('#BINARY_FILES="*.bin|*.dat|*.obj|*.mtl|*.b3d"
Strict
Import minib3d

Class Game Extends App
Field mesh:TEntity
Field copiedMesh:TEntity
Field cam:TCamera

Method OnCreate:Int()
SetUpdateRate 60
SetRender()
mesh = LoadMesh("monkey://data/Meshes/OBJ/dwarf2.obj")
copiedMesh = CopyEntity(mesh)
ScaleEntity(copiedMesh, 0.10, 0.10, 0.10)
ScaleEntity(copiedMesh, 0.10, 0.10, 0.10)
ScaleEntity(copiedMesh, 0.10, 0.10, 0.10)
ScaleEntity(copiedMesh, 0.10, 0.10, 0.10)
ScaleEntity(copiedMesh, 0.10, 0.10, 0.10)
ScaleEntity(copiedMesh, 0.10, 0.10, 0.10)
ScaleEntity(copiedMesh, 0.10, 0.10, 0.10)
ScaleEntity(copiedMesh, 0.10, 0.10, 0.10)
ScaleEntity(copiedMesh, 0.10, 0.10, 0.10) ' < - This one only has any effect
PositionEntity(copiedMesh, 0, 10, 0)
PositionEntity(copiedMesh, 0, 10, 0)
PositionEntity(copiedMesh, 0, 10, 0)
PositionEntity(copiedMesh, 0, 10, 0)
PositionEntity(copiedMesh, 0, 10, 0)
PositionEntity(copiedMesh, 0, 10, 0)
PositionEntity(copiedMesh, 0, 10, 0)
PositionEntity(copiedMesh, 0, 10, 0)
PositionEntity(copiedMesh, 0, 10, 0)
PositionEntity(copiedMesh, 0, 10, 0)
PositionEntity(copiedMesh, 0, 10, 0) ' < - This one only has any effect
RotateEntity(copiedMesh, 0, 10, 0)
RotateEntity(copiedMesh, 0, 10, 0)
RotateEntity(copiedMesh, 0, 10, 0)
RotateEntity(copiedMesh, 0, 10, 0)
RotateEntity(copiedMesh, 0, 10, 0)
RotateEntity(copiedMesh, 0, 10, 0)
RotateEntity(copiedMesh, 0, 10, 0)
RotateEntity(copiedMesh, 0, 10, 0)
RotateEntity(copiedMesh, 0, 10, 0)
RotateEntity(copiedMesh, 0, 10, 0)
RotateEntity(copiedMesh, 0, 10, 0)
RotateEntity(copiedMesh, 0, 10, 0)' < - This one only has any effect
cam = CreateCamera()
cam.CameraClsColor(0, 111, 0)
cam.PositionEntity(0, 0, -100)
AmbientLight(255, 255, 255)
Return 0
End

Method OnUpdate:Int()
If KeyHit(KEY_ESCAPE) OnBack()
TurnEntity(mesh, 0, 1, 0)
TurnEntity(copiedMesh, 0, 1, 0)
UpdateWorld()
Return 0
End

Method OnRender:Int()
RenderWorld()
Return 0
End

Method OnBack:Int()
EndApp()
Return 0
End
End

Function Main:Int()
New Game
Return 0
End')

All those "ScaleEntity" commands should shrink the copied mesh in to oblivion but it never gets smaller than 10%? As I've never used the original B3D, this could be part of the design but the docs don't mention it. The same thing happens when you try multiple translates and rotates too.

Unfortunately if your code has various transformation performed on a copied entity throughout your game, this means the final one wipes all the previous ones out. Logically the copied entity should act like a complete new entity IMHO, as far as having its own transformations that is.


AdamRedwoods(Posted 2014) [#227]
I'm not sure what you mean. Oh, i see. FOr this to happen, the original entity's matrix would have to be applied to the vertices.

In regards to the copiedMesh, the way it currently works is that Scale, Position, and Rotation are absolute (not relative) parameters. This happens in UpdateMat() of TEntity. It starts with the identity matrix, so everything else is overwritten, except if it has a parent via EntityParent().

To add on to Scale and Rotate, you must use
format_code('
ScaleEntity(copiedEntity, copiedEntity.ScaleX()*sc, copiedEntity.ScaleY()*sc, copiedEntity.ScaleZ()*sc)
')

On the other hand, commands like TurnEntity and MoveEntity and TranslateEntity add on to the existing matrix, instead of overwriting it. We could add one for ScaleEntity, call it RescaleEntity?


Sammy(Posted 2014) [#228]
I don't think you need to apply this to vertices, as long as a separate model transformation matrix is intact. This is the basis of an instanced model. I think the copied entity should initially have a copy of the original matrix but from that point on its transformation matrix should be unique to the copy. All rotations, translations, scaling should be performed on the copies unique matrix. As this is just a pointer copy, unlike CopyMesh, the vertices, normals etc. should remain pointing back to the original and act as a reverence, ala original B3D. This is already mostly in place but the current commands don't seem to realise fully that the copy should not reference the original matrix. It looks like there is an unneeded pointer back to the original matrix somewhere?


AdamRedwoods(Posted 2014) [#229]
i hesitate having to maintain 3 matrices, per entity update. image if you have instanced, scaled trees on two different rotating planets, that's at least 3*36=108 multiplies per tree (parent planet mat*tree orig mat*tree instance mat). think about instanced bones. did the original B3D maintain rescaled instances?

quaternions would be a better choice here, but that's a major overhaul. compare this with using a proposed Rescale() command or a ScaleMesh() command, which would be far less changes to the engine.

i'm not against using quats for everything, i've thought about it.


Sammy(Posted 2014) [#230]
I've maybe got the wrong end of the stick here Adam but I don't see why you need any extra matrices at all. The current copied model matrices will work fine when the model vertices, normals ect. are referenced from a different mesh. The original models model matrice can easily be ignored after this point. Also shouldn't calculations like scaling and translation should be combined in the one matrice before multiplication? I am not in front of my computer just now, so maybe miniB3D needs to do it in a certain way.

I don't think quaternions are needed unless slerps are required or gimbal lock show it's ugly head of course. ;) that said quaternions would generally be desirable but your correct, matrice-quaternion back and forth can be expensive and should be avoided unless the whole system is tailored for them.

I'll have a look myself tonight to see if there's a quick way around this, although I'm still a bit wary of the complex stuff like, the miniB3D matrix/child calculations.


Sammy(Posted 2014) [#231]
Edit: Sorry Adam, please ignore this for now, as I've just discovered that I changed some of the code within miniB3D last week and it may or may not be affecting this code. Argh, I need some sort of local VCS! :(

BTW, I like the idea of a relative scaling function ReScaleEntity()!

Same code as ScaleEntity except for the 1st 3 lines of the method...

format_code(' Method ReScaleEntity:TEntity(x#,y#,z#,glob=False)

sx *= x
sy *= y
sz *= z')


julesd(Posted 2014) [#232]
MiniB3D no longer works with beta versions of Monkey X. Using latest 78g.

Is this a dead project, or is it still being worked on?


DruggedBunny(Posted 2014) [#233]
Are you kidding? The maintainer posted only a week ago, three posts up!


Sammy(Posted 2014) [#234]
78g has only been out for less than a day. What was your error?


julesd(Posted 2014) [#235]
Had same problem with 78f as well.

line 450 in mojographics.monkey.

Method LoadSurface__UNSAFE__:surface( Surface:Surface,path$ )

Type 'surface' not found.

78g with current MinB3D, HTML5,. mojo bunnies example

I had changed one line to enable HTML5 now I get the error above.

If you try you will see what I mean.


AdamRedwoods(Posted 2014) [#236]
that's not used in minib3d, so you can just comment out the whole method.


julesd(Posted 2014) [#237]
Got it working, once you comment out that method, there is another method with error. I just commented that out as well, then it worked.

Thanks


LeeTheGee1(Posted 2014) [#238]
Hi All
i Have been using miniB3D for some time now and... i Love it...it reminds me of the Good old Blitz3D days "Okeey Dookey"...My Problem is that is have installed it in my Newish Windows 8.1 laptop...all the B3D Examples work within Monkey....HTML5 Target but when i try and run them independently all i get is a Blank Grey Screen...i have pre-loaded all the textures and #TEXT_FILES="*.txt|*.xml|*.json|*.obj|*.fx|" etc......i have tried everything for 2 days now....normal monkey apps run independently but not miniB3D ones...

any help would be Greatly appreciated i am running out of ideas

Lee


Xaron(Posted 2014) [#239]
Hi Adam,

I get a compile error in mojographics.monkey line 592 for the desktop target:
format_code('
'INTERNAL - subject to change etc.
Method OnUnsafeLoadComplete:Bool()
Return true
End
')

Overriding method does not match any overridden method.

Commenting that method resolves it.


AdamRedwoods(Posted 2014) [#240]
HTML5 Target but when i try and run them independently all i get is a Blank Grey Screen

you mean the html5 target? when you run this from the local machine, it will give you cross-domain security errors. go into the browser's console (ctrl-shift-j on chrome) and you'll see the errors. to run html5 locally, i use Node-Webkit, but it should work normally from a web server.

Commenting that method resolves it.

thanks! updated github.


LeeTheGee1(Posted 2014) [#241]
Wow Adam yes i did mean HTML5.....i just uploaded it to my Website and it worked perfectly...My Gosh i feel such a Twit....

Thanks Soo Much Man you are ACE

Coding Coding Coding

WoooHooo


Deen(Posted 2014) [#242]
Hi Adam,

miniB3D really rocks!.. Is that Collada(CAE) importer ready for miniB3D?

(syyhh!... if miniB3D is Collada + GLSL ready, then you can consider to start selling it.. please take my money at that time)


rebelas(Posted 2014) [#243]
Regarding Deen's comment, the same here, though I like to have rigid body physics too.


Deen(Posted 2014) [#244]
how can i view separated limb animation *.b3d in minib3d + Monkey X??

1. how to set separated limb animation in 3dsmax before exporting out into b3d (with b3d pipeline)? view the bones mesh? create dummy mesh and apply skin and add bones to them?
2. how to load b3d file with animation and animate them in monkey? sample codes maybe? how to load and animated b3d with separated limb animation? is that possible?


AdamRedwoods(Posted 2014) [#245]
1. not sure what you mean. blending animation?
2. you can try using LoadAnimSeq(file:String) which extracts animation. i don't know how well this works, and need to investigate it more.


julesd(Posted 2014) [#246]
Just a few questions.

Does MiniB3D use webgl in Html 5?
What platforms does MINIB3D currently support?
How many lights are possible in each platform ?


AdamRedwoods(Posted 2014) [#247]
> Does MiniB3D use webgl in Html 5?
yes
> What platforms does MINIB3D currently support?
linux, macos, winpc, flash, html5, ios, android, xna. i haven't tested ios in a while, though.
> How many lights are possible in each platform ?
linux, macos, winpc, ios, android with opengl1.1 = 8, opengl2=1, html5 = 1, xna=1, flash = 1
shaders get really slow with multiple lights. i haven't implemented a deferred light shader yet. the current shader could add more lights using an on-demand shader.


Landon(Posted 2014) [#248]

(syyhh!... if miniB3D is Collada + GLSL ready, then you can consider to start selling it.. please take my money at that time)



lol, i feel like throwing money Adam's way right now for all the hard work he has done. But alas 404 donation url not found. You guys would be surprised what i am doing with this over at the Realmcrafter Community edition site HUEHUEHUEHUEHUEHUEHUEHUE

that is if i can pull it off.


julesd(Posted 2014) [#249]
Just wondering is defered renderer being worked on?


AdamRedwoods(Posted 2014) [#250]
Just wondering is defered renderer being worked on?

i wish! i am excited to work on a light-indexed forward-render shader, but i feel a collada importer (animation and scene layout) is more important. this way we can load models consistently and use blender as a level editor. a new shader will be worked on eventually.


rebelas(Posted 2014) [#251]
Adam, I tried minib3D, it is nice. I thought I can make myself busy by converting Blitz3D samples to minib3D, but my mind moved into spending time on physics. I want to begin a small game physics library. What do you suggest for Vector 3D and Matrix library? Which version of OpenGL Monkey is using?


Sammy(Posted 2014) [#252]
Quick question from me... is there away of applying a specular map texture?

@rebelas: There are already vector libs and matrix libs in the miniB3D distro.

It's within the "maths" folder. (see "C:\..\Monkey Pro\modules\minib3d\math")


rebelas(Posted 2014) [#253]
Oh, yeah, and more. Thanks!


AdamRedwoods(Posted 2014) [#254]
>What do you suggest for Vector 3D and Matrix library?
i don't like the current minib3d vec, so use something like CannonJS's Vec3 API. this reduces "new" calls which are more important on html5 and mobile targets.
>Which version of OpenGL Monkey is using?
es1.1 and es2.0, depending on versions.
>is there away of applying a specular map texture?
texture blend mode 3 (additive)? i don't know how spec maps are usually colored.


rebelas(Posted 2014) [#255]
Thanks Adam, I keep in mind.


rebelas(Posted 2014) [#256]
Adam, I just learned about mojo3d, with that, do you still want to continue with minib3d?

http://www.monkey-x.com/Community/posts.php?topic=5548&page=first


Rone(Posted 2014) [#257]

* 'Mojo3d' - simple low level, gles2-ish 'immediate mode' 3d module for android, iOS, win8, html5 and glfw


sounds to me like something that would not be comparable to minib3d, but like a flat gles/d3d wrapper ... if it will ever be released, which I do not think :P
also it does not seem to be the case that this kind of of device/platform abstraction was planned for minib3d


Sammy(Posted 2014) [#258]
texture blend mode 3 (additive)? i don't know how spec maps are usually colored


Specular maps are a type of per pixel lighting, they represent texels within a texture that represent reflected light, they are usually a shader AFAIK. So it looks like miniB does not yet support them, I'll hang back a bit on this feature.


rebelas(Posted 2014) [#259]
Rone, what you say is true, however, one still wonder what is the reason to have mojo3D, while we have minib3d as open source 3D for Monkey?


rebelas(Posted 2014) [#260]
Even with mojo3D, and even if programmers begin making 3D libraries for it, direction might be toward scene graph or GUI Authoring tools, rather than entity system like Blitz3D. Thus, I think those who like Blitz3D, better forget Monkey, unless Adam comes with a miracle.


rebelas(Posted 2014) [#261]
Xors3D was a perfection for old Blitz3D, I finished a good working simulation with Xors3D. When it came to small devices, the whole project was abandoned. This goes to the mind of every engine programmer: why should I spend too much on a game engine while I can make lots of money by selling crappy $1 game for iPad, or get a job with great pay. I said somewhere else, it seems the solution is open source. When the cost of producing engine becomes more than cost of selling games, engine developers will move to selling games.


Rone(Posted 2014) [#262]

Thus, I think those who like Blitz3D, better forget Monkey, unless Adam comes with a miracle.
Xors3D was a perfection for old Blitz3D, I finished a good working simulation with Xors3D.


not...


however, one still wonder what is the reason to have mojo3D


- clean platform specific device abstraction
- mojo implementation using mojo3d
- maybe monkey to glsl/hlsl/agal

... minib3d also would benefit from it:
- removes most of the target specific code
- clean and especially fast mojo integration
- platform independent Trender implementations / much less redundant code


rebelas(Posted 2014) [#263]
That makes sense, but Adam, will you revise most of your codes to have a mojo3D based minib3D?


Sammy(Posted 2014) [#264]
I've been using multi-texturing for applying some simple decals but its proving to be a real pain under certain circumstances. I was wondering, is there a better way to efficiently create a decal texture on a mesh?


AdamRedwoods(Posted 2014) [#265]
I've been using multi-texturing for applying some simple decals but its proving to be a real pain under certain circumstances. I was wondering, is there a better way to efficiently create a decal texture on a mesh?

what circumstances? you man like uv unwrapping or problems with multi-texturing?


Sammy(Posted 2014) [#266]
No the multi texturing is working fine Adam, the problem is when I apply a decal texture to a mesh as a 2nd texture. The underlying meshes UV coordinates mess up the decal unless there extremely simple(planar). So applying a decal to a quad is fine as 2nd texture but if it's anything more sophisticated messes up the decal. I suppose a projected texture effect would be nice, or even a way to apply a 2nd set of UVs for texture two. Things are complicated as my level mesh generation is being procedurally generated, including the placement of decals, so avoiding UV seams is getting to be a real problem.


AdamRedwoods(Posted 2014) [#267]
there should be two sets of uv coords for every mesh. another trick is to duplicate the layer 0.0001 units away from the original layer, but this causes z-fighting for things far away from the camera. if this doesn't help, then i'm unsure what you're trying to do and would need some visual references for explanation.


Sammy(Posted 2014) [#268]
I can't duplicate the layers unfortunately as I am hoping to keep the scene polygon count down for mobile devices.

I can see no reference to using 2 sets of UVs, how is this achieved?


AdamRedwoods(Posted 2014) [#269]
format_code('
VertexTexCoords surface,vertex_index,u#,v#[,w#][,coord_set]
or
surface.VertexTexCoords ( vertex_index,u,v,w,coord_set )

Parameters:

surface - surface handle
index - index of vertex
u# - u# coordinate of vertex
v# - v# coordinate of vertex
w# - ignored
coord_set (optional) - co_oord set. Should be set to 0 or 1.
')
http://www.blitzbasic.com/b3ddocs/command.php?name=VertexTexCoords&ref=3d_cat


Sammy(Posted 2014) [#270]
Thanks Adam, I've never used that command before, it could be exactly what I need.


impixi(Posted 2014) [#271]
@AdamRedwoods:

The "HTML5 Game target" is broken with Monkey X Pro V079B + MiniB3d V0.42.3? I get a "Native OS Module not implemented" in os.monkey...

Also, what's the preferred approach for creating MiniB3d apps? Extend the MiniB3d.app class as in the "mojo bunnies" example? Or just extend the mojo app class like in the other examples?

I have posted an updated demo here: http://www.monkey-x.com/Community/posts.php?topic=374&post=87690 . I'd like to add a 2D overlay HUD to it. I suspect I'll need to restructure it to extend the MiniB3d.app class and make use of SetMojoEmulation(). Or is that more of an experimental thing?


impixi(Posted 2014) [#272]
When using the MiniB3DApp infrastructure, it looks like there is an issue with ClearWorld(). If called, a "memory access violation" error is generated from tpixmapgl.monkey.

To replicate the error just call ClearWorld() from an appropriate place in the minib3d_mojo_bunnies.monkey example.

EDIT: Using the "Desktop Game" target.


AdamRedwoods(Posted 2014) [#273]
The "HTML5 Game target" is broken with Monkey X Pro V079B + MiniB3d V0.42.3? I get a "Native OS Module not implemented" in os.monkey...


Yes, if anyone encounters this replace Import os with
format_code('
Import gametarget
')


Also, what's the preferred approach for creating MiniB3d apps?

If you don't extend the MiniB3DApp, then you will need to do your own init and PreLoadPixmap checking. Either way works just fine.
SetMojoEmulation() is not experimental, it is working. It must be called before using mojo commands in OnRender().


Xaron(Posted 2014) [#274]
Just to add, the "Import os" line is in monkeyutility.monkey in the minib3d folder.


impixi(Posted 2014) [#275]
Thanks. HTML5 works with that import mod... Though I'm not seeing any fog effects on that platform (Win8.1, Chrome and Firefox). Not supported?

I've modified my code to inherit from MiniB3DApp. Aside from the ClearWorld() issue, everything seems okay. Have got a little 2D HUD working now. Thanks again.


Sammy(Posted 2014) [#276]
VertexTexCoords + coord_set = 1 does not work I am afraid. I've tested it in various scenarios and always the 2nd texture uses the 1st textures UV coords. I double checked that the meshes VertexDataBuffer had all the correct values poked in and everything seems fine(extra 2nd UVs at offset of 8 & 12 + 48 per vert index). Nothing you do to the 2nd set of UVs + texture seems to make any difference unfortunately, they just seemed to get ignored in preference to the 2nd texture using the 1st textures UV coords.

BTW. A quick and dirty confirmation method Adam, is simply to, VertexTexCoords('all verts',0,0,,1) for your 2nd texture which has no effect in the UV placement, when it should blank them.


Sammy(Posted 2014) [#277]
Did you get a chance to look into this Adam? It's got me stumped and it looks like a feature I really need.


AdamRedwoods(Posted 2014) [#278]
not yet. does it not work for all targets?


Sammy(Posted 2014) [#279]
I've only tested it properly on GLFW Adam. Unfortunately my Android tablet is on the blink. HTML5 has the same problem IIRC.


Sammy(Posted 2014) [#280]
Adam, I stuck this straight into my game as a method but I could bang out some sort of sample, say a model with 2 textures using 2 UVs sets as a small test program, if that would help?


AdamRedwoods(Posted 2014) [#281]
yes, if you have a test program, send it over to my email.


Sammy(Posted 2014) [#282]
OK, I'll get on it tomorrow if I can or Monday at the latest Adam.


Sammy(Posted 2014) [#283]
OK, posted a .RAR and some notes Adam. I am a little worried about this one, I hope its an easy fix.


EdzUp(Posted 2014) [#284]
@Adam: what targets are supported by monkey minib3d?


Sammy(Posted 2014) [#285]
I've tried Android, Windows and HTML5, all work well for me.


EdzUp(Posted 2014) [#286]
I've been using linux, I want to release on android, iOS, Mac/windows/linux, and windows 8


Sammy(Posted 2014) [#287]
Quick question, is there any way I can insert my own opengl commands into a cameras render pipeline without hacking into the miniB3D source?


AdamRedwoods(Posted 2014) [#288]
Quick question, is there any way I can insert my own opengl commands into a cameras render pipeline without hacking into the miniB3D source?

hmmm. not sure what you need to do, but i'm guessing you need to add it AFTER the camera calls its own driver commands.
if that's the case, there really isn't a good way to do that, because it wasn't really planned for that. the API has access to most camera commands.

the only way i can think of is you can add it per mesh class, by Implementing IRenderUpdate() for the mesh. This is how sprites update their camera. It is only called if the mesh is viewable (not culled) -- BUT this is probably not what you want.
format_code('
Class TSprite Extends TMesh Implements IRenderUpdate
...
Method Update(cam:TCamera )
'' called during render()
...
')


Sammy(Posted 2014) [#289]
I have some old particle code for another language that I wrote before MonkeyX that would like to see if it could work within miniB3D. It uses some wacky GLES (eg. degenerate vertex arrays) to achieve the effects at speed. I'd probably be better off learning to do it within a shader but it's mainly for fun at the moment.

Thanks for the tips though Adam, I had a quick look at how TSprite(and TBatchSprite) does it and its certainly a novel method that should be useful.


Xaron(Posted 2014) [#290]
I get compiler errors with Monkey 79d as Mark has fixed some "public/private" related stuff:

format_code('MonkeyPro/modules_ext/minib3d/tmesh.monkey<213> : Error : Method TEntity.UpdateMat:Void(Local load_identity:Bool) is private.')


DruggedBunny(Posted 2014) [#291]
Just ran into the same problem as Xaron!


AdamRedwoods(Posted 2014) [#292]
yup, in progress. testing my new solution with Matrix getters/setters because UpdateMat() is specialized for Position, Scale, etc. will try to update late tonight.


Sammy(Posted 2014) [#293]
Thinking of updating to 79, was the matrix problem sorted out for everyone?


AdamRedwoods(Posted 2014) [#294]
i updated it but did not test it.


Sammy(Posted 2014) [#295]
Ah, cool Adam, I'll give it a go this weekend.


EdzUp(Posted 2014) [#296]
Does this work with the latest monkey yet or is it still broke?


Sammy(Posted 2014) [#297]
Stuck in a hotel, waiting for car to be fixed I'm afraid. So I can't test it I'm afraid.


eNano(Posted 2014) [#298]
Hello Adam I'm new on this community and new on Monkey, I was really hoping to try minib3d but I had some troubles trying to install the module.
This is what I have so far:
- I've copied the module in modules folder and renamed to minib3d.
- I had the error that says "Native OS Module not implemented" so I did what you said in a post and changed the line in monkeyutility.mokey to "import gametarget" instead of "import os".
- I'm trying to run the example file firepaint3d.monkey but when I run it (using html5 Game - release) it jumps to mojographics.monkey and stops in " Method LoadSurface__UNSAFE__:Surface( surface:Surface,path$ ) " and gives this message: "Overriding method does not match any overridden method."
- I've tried with Android target and with other examples but the error is the same.
What could be wrong?
Thanks for all!


AdamRedwoods(Posted 2014) [#299]
I think i fixed some of those problems with the latest on GitHub, so you can try to download, or even copy/paste the code again.
Method LoadSurface__UNSAFE__ should be removed. It's not needed.


eNano(Posted 2014) [#300]
Cool it works! thanks a lot!


eNano(Posted 2014) [#301]
What could be the best way to do some basic UI elements with minib3d?
I need to draw some rectangles, frames and text over the 3d scene for context menus and stuffs like that, I've tried to play with SetMojoEmulation() but I have some bugs with DrawText()
Thanks!


AdamRedwoods(Posted 2014) [#302]
SetMojoEmulation() triggers the Mojo-esque layer of the renderer. You can then do things as you normally do with Mojo. Then you must end with RenderWorld().
If there are bugs with DrawTest() point them out to me and I will have a look, but everything else should work.


eNano(Posted 2014) [#303]
Thanks a lot, that was the problem. I was drawing a rectangle, then I called RenderWorld() and after that I used DrawText(). Another thing that I was doing wrong is call SetMojoEmulation() before the Init() method, that was giving me the message " **Image Not Preloaded: monkey://data/mojo_font.png "
Thanks!


Deen(Posted 2014) [#304]
how is your COLLADA importer mate? is there any light? :)


Xaron(Posted 2014) [#305]
Still two issues:

Method New in TColTree is still private.

And... are the problems with CameraPick atm?


AdamRedwoods(Posted 2014) [#306]
how is your COLLADA importer mate? is there any light? :)

no time! still fixing octree bugs. will get to next.

And... are the problems with CameraPick atm?

hmm. does the pick_collision example work? i thought this was only with monkey 78g. i'll see if i can install the github version and test it.


Xaron(Posted 2014) [#307]
Adam that example works great but just try this, replace the sphere with a simple cube, move the camera away a bit and try to hit the right or the lower face of the cube. It works but not that well in some areas. Don't know if this is a scale problem as a face has only 2 triangles?

format_code('
sphere1 = CreateCube() 'CreateSphere(20)
sphere1.ScaleEntity(10,10,10)
')

All in all it's only a small issue.

What really bugs me is that when I have cube 1 in front of cube 2 which is in a line with the camera I always get the last object on that line picked even though PickedXYZ returns the (correct) front object. I'll do an example...


Xaron(Posted 2014) [#308]
So here's an example I get headachse:

format_codebox('
Import minib3d

Function Main()
New Game
End

Class Game Extends App
Field cam:TCamera

Field light:TLight
Field cube1:TMesh
Field cube2:TMesh
Field dot:TMesh

Field init_gl:Bool = False

Field cz:Float, pm:Int

Method OnCreate()
SetUpdateRate 30
SetRender()
End

Method Init:int()
If init_gl Then Return 1

If Not TPixmap.PreLoadPixmap(["mojo_font.png"]) Then Return 0
init_gl = True

cam = CreateCamera()
cam.CameraClsColor(0,0,80)
cam.PositionEntity 0.5,1,-5

light=CreateLight(1)
light.PositionEntity 0,3,-3

dot = CreateSphere(5)
dot.ScaleEntity(0.2,0.2,0.2)
dot.EntityColor(0,255,0)

cube1 = CreateCube()
cube1.NameEntity( "Cube 1" )
cube1.EntityPickMode(2)
'cube1.CollisionSetup(1, COLLISION_METHOD_POLYGON, 1.0)
cube1.EntityFX(2)
cube1.RotateEntity(145,145,0)

cube2 = CreateCube()
cube2.NameEntity( "Cube 2" )
cube2.EntityPickMode(2)
cube2.PositionEntity(3,1,5)
'cube2.CollisionSetup(1, COLLISION_METHOD_POLYGON, 1.0)
cube2.EntityFX(2)
cube2.RotateEntity(145,145,0)

Print "main: intit done"

Return 1
End

Method OnUpdate()
If KeyHit(KEY_CLOSE) Or KeyHit(KEY_ESCAPE) Then Error ""

If Not Init() Then Return

If KeyDown(187)
'anim_time += 1
cz +=0.1
cam.CameraZoom(cz)
End
If KeyDown(189)
'anim_time -= 1
cz -=0.1
cam.CameraZoom(cz)
End

If TouchDown(0)
Local e:TEntity = cam.CameraPick(TouchX(), TouchY() )

Local surf:TSurface = PickedSurface()
Local v0:Int, v1:Int, v2:Int

dot.PositionEntity(PickedX(), PickedY(), PickedZ() )

If surf
v0 = surf.TriangleVertex( PickedTriangle(), 0)
v1 = surf.TriangleVertex( PickedTriangle(), 1)
v2 = surf.TriangleVertex( PickedTriangle(), 2)

'Print "*** "+v0+" "+v1+" "+v2

surf.VertexColor(v0,255,0,0)
surf.VertexColor(v1,255,0,0)
surf.VertexColor(v2,255,0,0)

'surf.RemoveTri( PickedTriangle)
Endif

If Not e Then Print "null pick" Else Print e.classname + " " + e.EntityName()
Endif
End

Method OnRender()
If Not Init() Then Return
RenderWorld()
End
End
')

Basically it's your example with two cubes. I can pick the front one easily but get no camera pick on the second one...


AdamRedwoods(Posted 2014) [#309]
FYI - I've one last bug to fix with the next version, but. Sometimes one bug leads to others. Keep fingers crossed!


Sammy(Posted 2014) [#310]
Cool, looking forward to the release Adam.


Sammy(Posted 2014) [#311]
This small routine seems to drive the 2D emulation nuts for some reason. Lots of graphical blending glitches.

format_code(' Function Text(text:String, x:Int, y:Int, center_x:Float = 0.0, center_y:Float = 0.0)
Local b:Int = GetBlend
SetBlend AdditiveBlend
DrawText(text, x, y, center_x, center_y)
SetBlend b
End Function')

Blending does not seem to work on text at all BTW. Repeatedly calling of Text() in the one frame, seems to drive the blending nutty in GLFW at least. SetBlend() seems to create a new blending layer if the previous layers blend is not the same as the new one, which can happen very easily. So it looks like if you call SetBlend at lot, blending gets corrupt?


AdamRedwoods(Posted 2014) [#312]
SetBlend() seems to create a new blending layer if the previous layers blend is not the same as the new one, which can happen very easily.

correct, it's the only way i could do it off the top of my head. i wonder if another way would be to associate a layer per blend value?
blending should work with text, though, i'll look into it.


nigelibrown(Posted 2014) [#313]
Is miniB3D capable of outputting to dual screens? Are there any examples of how to achieve this? I have a dual head graphics card and need to go fullscreen on both! in FULLSCREEN mode


Sammy(Posted 2014) [#314]
i wonder if another way would be to associate a layer per blend value?


I think that's a much better idea Adam, it should be quicker(less surfaces) and also much closer to how the original blitz basic engine operates too.


AdamRedwoods(Posted 2014) [#315]
Is miniB3D capable of outputting to dual screens?

i had to look this up, but it seems you would have to create two window contexts, which GLFW3 can do, but the current GLFW2.x that monkey is using is out of date:
http://www.glfw.org/docs/3.0/monitor.html

So the answer is sadly, no. i've pushing Mark to get a GLFW3 update for a long, long time.


Sammy(Posted 2014) [#316]
Isn't two screens just seen, virtually, as a single monitor with a combined resolution of the two monitors? Therefore you could just split that res into two different camera views?


AdamRedwoods(Posted 2014) [#317]
two camera views would center the perspective point in the center of each of the two views, which isn't correct, it needs to go in the middle of the two monitors. some gfx cards will treat a full screen as one opengl view, which then miniB3D will handle that (but I think it's activated by a manual setting-- too dependent upon drivers).


Sammy(Posted 2014) [#318]
Interesting, I have a dual monitor setup, I'll try this today to see how MB3D handles my setup.


julesd(Posted 2014) [#319]
Just wondering if this is still on going, when I go to github, the dates for the files are from a while back.

I noticed the bunny demo has 2d overlayed on top of 3D, is it posible to use this to create a GUI for miniB3D?


Sammy(Posted 2014) [#320]
@Julesd:

Feature-wise, things have slowed a little but Adam is still on top of any bugs that people come across.

The 2D functions can be used for a GUI. I rely on them for my own games 2D elements(Buttons, map, score, onscreen joypad etc) and it works very well.


@Adam:

I can't seem to get SetScissor() to work with the Mojo emulation, is this to be an expected limitation?


AdamRedwoods(Posted 2014) [#321]
I can't seem to get SetScissor() to work with the Mojo emulation, is this to be an expected limitation?

should work? does it not scissor anything?
Just wondering if this is still on going

i'm still here, i'm stuck on a nasty, brain-burning bug with the octree.


Landon(Posted 2014) [#322]
Question is there some kind of LoD going on behind the scenes i can't find???. Reason for that is if i manually change the vertices of a mesh only half of them seem to actually move, but if i clear the surface and rebuild it with the new vert coords it works fine.

But that is really slow and i'd just like to push all that info into a buffer if possible, i made a working CAL3D module that can use minib3d as a renderer but when i try pushing the vertices into the model only half of them move.

Here is a demo of it working using minib3d Cal3d mesh + skeleton and animation files

http://vigilsoft.net/cal3dtest/
(Press S to back up the cam and Up to look up, i haven't centered the model yet.)

This is how it is supposed to look (but slow because of the surface clear)


This is how it looks just pushing the vert position data only




Landon(Posted 2014) [#323]
erm nvm i guess i have to clear the surface, i tried using cached tri info and the normals went crazy, even if i use the calculated normals Cal3d spits out, in the end it seems that is just how cal3d works each render it gives you a vert,tri,norm,tex coord buffer that you have to slap back on the mesh with each render.

anyways i managed to do it now without the speed hit.

i've sort of always prefered cal3d as a model/animation library over b3d but i've never managed to get them to work together until now. This actually doesn't use anything other than TMesh to render the animations and models.


Sammy(Posted 2014) [#324]
@Adam:

I'm away from my PC just now. It seemed to be not working at all. I'll do some further SetScissor() tests when I get back.


Sammy(Posted 2014) [#325]
Here is a small test program that illustrates the SetScissor() problem.

format_codebox('Strict
Import minib3d

Class Game Extends App
Field mesh1:TEntity
Field cam:TCamera

Method OnCreate:Int()
SetRender()
mesh1 = CreateCube(); ScaleEntity(mesh1, 0.5, 0.5, 0.5)
cam = CreateCamera()
cam.CameraClsColor(50, 111, 0)
cam.MoveEntity(0, 0, -3)
AmbientLight(255, 255, 255)
SetUpdateRate(60)
Return 0
End

Method OnUpdate:Int()
If KeyHit(KEY_ESCAPE) OnBack()
TurnEntity(mesh1, 0, 1, 0)
UpdateWorld()
Return 0
End

Method OnRender:Int()
RenderWorld()
SetMojoEmulation()
SetScissor(200, 100, 200, 200)
DrawText "01234567890012345678900123456789001234567890_TEST_01234567890012345678900123456789001234567890", 320, 240, 0.5,0.5
Return 0
End

Method OnBack:Int()
EndApp()
Return 0
End
End

Function Main:Int()
New Game
Return 0
End')

I'm kinda hoping its me that's doing something wrong here as it would be functionality that would be sorely missed.


Sammy(Posted 2014) [#326]
Any luck with this Adam? I'm working around it but if I can get it working it would mean that I could use my GUI.


AdamRedwoods(Posted 2014) [#327]
RenderWorld() should go last. I'll look into this, but may not have time until Tues.


Sammy(Posted 2014) [#328]
Whoops, I'll try it with RenderWorld() in the correct position.

No problem Adam, no hurry, it's not workflow stopper just an inconvenience for now.


Sammy(Posted 2014) [#329]
Edit:

Nope, the SetScissor() command only acknowledges the last call before RenderWorld(). Therefore you can't call SetScissor() more than once each render loop. Not sure if there is a way around this?

format_code('Strict
Import minib3d

Class Game Extends App
Field mesh1:TEntity
Field cam:TCamera

Method OnCreate:Int()
SetRender()
mesh1 = CreateCube(); ScaleEntity(mesh1, 0.5, 0.5, 0.5)
cam = CreateCamera()
cam.CameraClsColor(50, 111, 0)
cam.MoveEntity(0, 0, -3)
AmbientLight(255, 255, 255)
SetUpdateRate(60)
Return 0
End

Method OnUpdate:Int()
If KeyHit(KEY_ESCAPE) OnBack()
TurnEntity(mesh1, 0, 1, 0)
UpdateWorld()
Return 0
End

Method OnRender:Int()
SetMojoEmulation()
SetScissor(200, 100, 200, 200)' Ignored
DrawText "01234567890012345678900123456789001234567890_TEST_01234567890012345678900123456789001234567890", 320, 240, 0.5,0.5
SetScissor(0, 0, DeviceWidth(), DeviceHeight())' Because of this line.
RenderWorld()
Return 0
End

Method OnBack:Int()
EndApp()
Return 0
End
End

Function Main:Int()
New Game
Return 0
End')

I 'think' the problem is that the SetScissor() command is just modifying the current camera clip plane as opposed to inserting a glScissor() GL command into the rendering pipeline?


Sammy(Posted 2014) [#330]
Strange, I am not sure there is something wrong with SetBlend(), I just noticed that if I draw some blank quads after printing some text to the screen, then the quads have a garbled version of the font texture within them. It's almost as if the current surfaces brush is using the previous font texture when drawing quads in the mojo2d emulation.


AdamRedwoods(Posted 2014) [#331]
hi, sorry i haven't had any time, been moving the family to a new place. but i will look at this as soon as i can!


Sammy(Posted 2014) [#332]
No problem Adam, thanks for the update and good luck with the big move.


Landon(Posted 2014) [#333]
Hey i keep getting Error #3697: A texture is bound on sampler 0 but not used by the fragment program

whenever i create a flash build, it's only when i try to load a b3d file that is using lightmapping.


EdzUp(Posted 2014) [#334]
With the latest stable monkey I get loads of 'x is private' errors for different classes in the build

Edit: It was TColTree that was the problem 'TColTree.new() is private' going into the TColTree.monkey file and putting a Public before the Method New() allows it to compile at least :D


AdamRedwoods(Posted 2014) [#335]
Hey i keep getting Error #3697: A texture is bound on sampler 0 but not used by the fragment program

whenever i create a flash build, it's only when i try to load a b3d file that is using lightmapping.

i wonder if there's an empty texture somewhere. the renderer is suppose to fill in empty textures with a null texture for Flash to keep it from complaining.


Landon(Posted 2014) [#336]
yea i'm not sure what happened it was a map that had a bad material somewhere (lightmapped) i'm still looking into this myself but i got around it by being very careful with texture assignments when i exported the map and it seemed to clear itself up.

Also i just committed a fork this morning containing the changes i made that added lightmaps for html5, Loadanimseq and fixed some child entities not updating properly when the parent is a bone.

I was considering adding the TTerrain code that was created for minib3d on bmax over to monkey if you didn't mind, i know you have your hands full but i'd like to help out where i can.


Cocopino(Posted 2014) [#337]
Hi, thanks for this amazing module.
I think I found a bug though in the CameraPick command, which would be the main way the user should interact with my game-to-be.

Illustration of the problem below:

format_codebox('
Import minib3d

Function Main()
New Game
End

Class Game Extends App

Field cam:TCamera
Field cube:TMesh
Field update:Int
Field updateRate:Int = 30
Field touchCount:Int = 0

Method OnCreate()

SetUpdateRate updateRate
SetRender()

cam = CreateCamera()
CameraClsColor(cam, 100, 100, 200)
cam.PositionEntity 0.5, 2, -5

cube = CreateCube()
cube.NameEntity("Cube 1")
cube.EntityPickMode(2)

End

Method OnUpdate()

If KeyHit(KEY_CLOSE) Or KeyHit(KEY_ESCAPE) Then Error ""

If TouchHit()

Local e:TEntity = cam.CameraPick(TouchX(), TouchY())

If Not e Then
Print update + " You missed!"
Else
touchCount += 1
Print update + " " + e.classname + " " + e.EntityName()
EndIf

EndIf

'start moving the cube around every second after 5 picks/touches
If (touchCount > 4)
update += 1
If (update Mod updateRate) = 0
cube.MoveEntity(0, 0.2, 0)
EndIf
EndIf

UpdateWorld()

End

Method OnRender()

RenderWorld()

End
End
')

The first 5 touches/picks will be fine, then the cube will start moving. As soon as it has moved a little, camerapicks stop working.
In another thread someone mentioned "Camerapicks don't work anymore", suggesting a prior version did work correctly. Does anyone know which version he could be referring to, or even better yet, is this a known problem that is on the todo list?

Thanks!


Xaron(Posted 2014) [#338]
I'm having the same CameraPick issue. I know you've quite some workload Adam, have you had a chance to look at it yet? Thanks! :)


EdzUp(Posted 2014) [#339]
Is this project still active?


Hezkore(Posted 2014) [#340]
I'd also like to know if this is still active...


Sammy(Posted 2014) [#341]
Looks dead to me.


adekto(Posted 2014) [#342]
i got Error : Method TColTree.new() is private.
and Public is already befor Method New() no clue what to do here


Playniax(Posted 2014) [#343]
Just remove the private and it shoudl work...


adekto(Posted 2014) [#344]
there is no private, and it still gives the same error


Duke87(Posted 2014) [#345]
therefor you go to
minib3d/tcoltree.monkey

Search for the Class TColTree

[line 42 or something] and comment out
'Private

Global searchNode:Node[128]

Method New()

End Method

...


EdzUp(Posted 2014) [#346]
Or put 'Public:' in front of the new method


EdzUp(Posted 2014) [#347]
@AdamRedwoods: Check ya email :)

Update: Adam has said via email that he's still looking at octrees and locating a bug in there but its still being worked on.


EdzUp(Posted 2014) [#348]
Does anyone have code to change the viewport in game after the glfw res stuff, I change the resolution using the monkey commands and that works but the new res causes flicker like the viewport for minib3d is not updated. This is the Linux build haven't tried it on windows yet.

It appears that the res change has no effect on windows, on nix it causes the flickering only when using minib3d


k.o.g.(Posted 2015) [#349]
Is there any model format out there, which can handle animations (except b3d) and minib3d support it


AdamRedwoods(Posted 2015) [#350]
[q]Is there any model format out there, which can handle animations (except b3d) and minib3d support it[/q]
Not currently. I do have an incomplete Collada importer, which is a part of my plan to get a Blender->MiniB3D pipeline.


k.o.g.(Posted 2015) [#351]
@AdamRedwoods
thanks for you answer

me and my mate working on a basic FBX Importer (only version 2010)


Landon(Posted 2015) [#352]
i have a cal3d library that works with monkey minib3d. it also has spring systems for flowing hair and capes. i should probably put it on github or something.


k.o.g.(Posted 2015) [#353]
@Landon
That would be great :)


Landon(Posted 2015) [#354]
https://code.google.com/p/monkey-cal3d-minib3d/

Still pretty early in development, working out the kinks and such. added the blitzmax version i made as well.


EdzUp(Posted 2015) [#355]
@Adam is free entity in there yet?


petimat(Posted 2015) [#356]
CameraPick issue can be solved by commenting out the "If col_obj.RaySphereTest(..." line and its EndIf (but not the code between them!) in tpick.monkey ,inside the Pick() function.It's not the best solution because there is no quicktest then.I think the col_info.ray_dir is just not the right value that we would need.I replaced RaySphereTest function with my own so now it works for me.


MikeHart(Posted 2015) [#357]
Is MiniB3d using standard OpenGL stuff to render, or is shader and OpenGLES based?


AdamRedwoods(Posted 2015) [#358]
Is MiniB3d using standard OpenGL stuff to render, or is shader and OpenGLES based?

Both!
The basic import minib3d is opengl1.1es.
format_code('Import minib3d.opengl.opengles20')
is the opengl2.0 with shaders. The default shader is currently my own standard pipeline emulator.

of course, with XNA and Windows Phone, it uses something else.

In the future I hope to focus solely on shaders.


MikeHart(Posted 2015) [#359]
Thanks for the info. For the game I am working on with my wife, we want to go the 3D route. Will check out MiniB3D intensively when the first character models are created and animated. I already saw that MiniB3d supports the most important file formats. Which is good.


EdzUp(Posted 2015) [#360]
The only issue I have had is freeentity not removing the entity so its stuck in the 3d world, its very capable as a engine but there are a few niggles that once sorted would be brilliant.

Niggles I have is:
1)freeentity not getting rid of entity from 3d world
2)changing resolution in game doesn't scale the camera viewport

If those were sorted it would be solid as a engine :)


Landon(Posted 2015) [#361]
yea what i ended up having to to do in that cal3d port is clear the surfaces to remove stuff.


Salmakis(Posted 2015) [#362]
Hey, is it really working with HTML5 Target?
i wanted just to try some examples, but the precompiler stucks at
format_code('
#If Not BRL_OS_IMPLEMENTED
#Error "Native OS Module not implemented"
#Endif
')
in os.monkey :(
afaik brl.os is not aviable in the HTML5 target
(monkey Version: 81b)


Landon(Posted 2015) [#363]
was that the issue from monkeyutility calling import os instead of Import gametarget?


AdamRedwoods(Posted 2015) [#364]
was that the issue from monkeyutility calling import os instead of Import gametarget?

Yeah, you can just remove Import os. I don't think it needs it, it was for the LoadString which got moved.
I really need to update miniB3D. I wish I could sign up for a programming retreat somewhere in the mountains.


DruggedBunny(Posted 2015) [#365]
Wow, I had no idea -- I thought I'd read that it worked on HTML5 but ran into the same error!

It seems to work here, has a few 'shader linking errors' but seems to run. Cool!


Carlo(Posted 2015) [#366]
i have a error

Class TMesh Extends TEntity

Field col_tree:TColTree=New TColTree
Error : Method TColTree.new() is private.

thanks

Carlo


Landon(Posted 2015) [#367]
then make it public like the dirty french stripper she is.


diemar(Posted 2015) [#368]
I seem to have the same problem.

Can somebody give me a line of code how to fix that private problem?
THX


EdzUp(Posted 2015) [#369]
Go into the TColTree class and put Public on a new line above the New method/function this will tell the parser its public and stop the error


diemar(Posted 2015) [#370]
Thanks for the quick answer! Long time not seen.

Now I'm getting to a good old "Memory access violation", and a line "glBindBuffer(GL_ARRAY_BUFFER,0)" of opengles11.monkey is highlighted.

Don't know much about GL, so this seems to be a tough one.


EdzUp(Posted 2015) [#371]
That is not one of the minib3d errors and relates to binding a opengl data buffer. Does the machine support vbos?


diemar(Posted 2015) [#372]
I even don't know what vbos is :-/


EdzUp(Posted 2015) [#373]
Vertex Buffer Objects some old cards don't support them, iirc minib3d was coded to allow for old cards to use it but it might be a old version of minib3d before they were added.


diemar(Posted 2015) [#374]
Are they reqired? Or can I rem them out somehow?

I'd be glad having some simple rendering.


EdzUp(Posted 2015) [#375]
If you downloaded the latest minib3d build it should not be required, however some of the minib3d systems have serious issues with monkey.

These are:
1) glfw3 - z order is miffed
2) resolution changes - this can screw up minib3d
3) issues with freeing entities - creating and freeing entities can cause issues with entities remaining in the game just stationary dead ones.


diemar(Posted 2015) [#376]
That's no biggie, as long ad I can port a simple Blitz3D Code, with a few modifications. I mean, simple in terms of 3D, but complex AI.


EdzUp(Posted 2015) [#377]
Its always good to know though :)


diemar(Posted 2015) [#378]
Yeah sure, Thanks again. Do you think my older laptop doesn't support the min. OGL version?


diemar(Posted 2015) [#379]
wow I got it working. Had to rem out 4 of then glBind thingies. Cool.


EdzUp(Posted 2015) [#380]
It works great on glfw2 :)


diemar(Posted 2015) [#381]
the fps are fluctuating a lot, from 30 to 1, any idea what could be the cause? It seems illogical.


EdzUp(Posted 2015) [#382]
It really depends on ya code one thing I can recommend is dont load entities or texture s lot.

Freeing entities is also a nono


diemar(Posted 2015) [#383]
it's just the sample that comes with it, animation_test.monkey, with 4 NPCs, not animated tho. fps starts smoothly at 30 after about 5s it starts jumping between 1 and 15. Strange. Priority problem maybe.


diemar(Posted 2015) [#384]
After reming out those 4 zombie NPCs, I seem to have a steady framerate. Tho, I would expect that with 14 Triangles in the scene.

I started trying to port a 30kb Source, learning by doing. After 8 Hours of partially very redundant editing, I am getting an opinion about MiniB3D for monkey.

I don't like the Case sensitive feature, not Recognizing eg. createcube(), but for instance the correct MilliSecs() as saved by the Blitz IDE is not recognized, but Millisecs() works, which I'd consider a bug.

Basicly there seems to be a LOT of manual converting to certain nontolerant MiniB3D standarts that are pretty far away from common Blitz code.

So I think what is really missing is a Code processor that is capable of converting most old Blitz3D code to a hybrid monkey Project sourcecode in which the 3D department is handled by MiniB3D and the rest by monkey / mojo itself, eg. file handling, 2D etc.

That being said, I am a late bird and a total beginner with monkey. Maybe I should read more in the beginners section ^^












.


Xtie(Posted 2015) [#385]
Hi,

I'm trying the latest MonkeyX and minib3d, desktop version builds ok but with HTML5 I get this error:

format_code('Error : Unable to find overload for glDrawElements(Int,Int,Int,DataBuffer).')

I also tried format_code('import minib3d.opengl.opengles20') with the guide here


Landon(Posted 2016) [#386]
just comment it out, it's for wireframe drawing. also comment out the one right below it under

format_code('

If vbo

glDrawElements(GL_TRIANGLES,surf.no_tris*3,GL_UNSIGNED_SHORT, 0)

Else

'glDrawElements(GL_TRIANGLES,surf.no_tris*3,GL_UNSIGNED_SHORT,surf.tris.buf) <---- comment this guy out

Endif

')


Landon(Posted 2016) [#387]
Hey one little fix i recommend in tpixmaphtml5.monkey

format_code('

Method PreLoadData:Void(f$, id:Int)
''we can do this with buffers, when available
'' then also expand this class as the Buffer Callback

If id<1 Then Return

f = FixDataPath(f)
If f.Find("monkey://") > -1 then
f=f.Split("//")[1] 'for the html5-- native class doesn't use monkey:// prefix
Endif
Local d:PreloadData = New PreloadData
d.id = id
d.data = LoadImageDataHTML(f, id)

p_map.Set( id, d )

End
')

swap the function out with the one above, this allows you to preload external textures from your webserver.

then when preloading you can use

format_code('
TPixmap.PreLoadPixmap(["http://vigilsoft.net/Zombie.jpg","mojo_font.png"])
')


then later on use something like this
format_code('
If TPixmap.IsLoaded( "http://vigilsoft.net/Zombie.jpg" ) And hasz = False
EntityTexture(zombie[0],TTexture.LoadTexture(TPixmap.LoadPixmap("http://vigilsoft.net/Zombie.jpg")))
hasz = True
Endif
')


EdzUp(Posted 2017) [#388]
Does anyone have a glfw3 version of this as all the z ordering is messed up on glfw3