MiniB3D Thread 3

BlitzMax Modules Forums/MiniB3D/MiniB3D Thread 3

Thread 2

Latest Version: 0.27 - download from here.

0.27 features a few bug fixes, mostly relating to sprites which are now always displayed correctly and also a few other things.

You are getting worst than Mark into making updates...:D

nice solid work thanks for sharing

Simonh, I really appreciate all your hardwork on this project it's really helping out.

Sweet! Talk about quality (and responsiveness)!

What a great tool you've created!

is the link dead or just me who can't access to the website ?

works fine here.

Note, How can use linepick method with minib3d ?

Special message For Boby, çà marche impec l'ami.

LinePick is not implemented yet.

strange issue... it 's the only link that i can't access. I can't solve it . Maybe anyone could post a mirror Link to download ? It would be lovely :)

I assume Simon doesn't mind, since it's a public download.

It's in my temp folder, so don't expect it to stay there for ever, but since you're having problems.

http://www.glimmergames.com/temp/MiniB3D-v027.zip

has anyone been able to get entitypick or camerapick to work? I've tried and failed.

Many thanx ! I try it in the minute.
[edit]
Many works done. really good !

But for the moment, there are so many functions not available, that i really often use like "CreateTexture" ,"TextureBuffer" , "getSurfacebrush" etc... and of course the TForm functions. So for the moment, i keep a look on this, but i can't use it.

Continue, it's really a good work !!!

What do people use for 2D with MiniB3D? Anyone hacked Max2D to work with it? I saw it somewhere in the forums, but can't find it ATM.

About meshwidth, meshdepth and meshheigth functions, i received always 2.0

I had tested with different mesh the value returned for the theses functions is always 2.

I don't understand why ?

Another problem about CountSurfaces.

When i use this functions, i received for my mesh value 0.

I test the same function CountSurfaces whit the same mesh in blitz3d the returne value is 4.

While I haven't testet it, the code for meshwidth etc. looks valid.

As for CountSurfaces it's used heavy internally, so that's probably ok too. Please re-check your results :)

We really should make Max2D support a priority in MiniB3D. It's such a pain doing it yourself each time :)

Hmm. Did some work on converting entity position to screen coords (for labels over objects etc.), but only the x position is correct.
The y Position keeps moving up for some odd reason.
I know the returned Y is reverse from normal.

' Object to screen stuff
	Method ObjectToScreen:TVector(Entity:TEntity)
	
		Local SX:Double
		Local SY:Double
		Local SZ:Double
		Local MVMatrix:Double[16]
		Local ProjMat:Double[16]
		Local VPort:Int[4]
		glGetDoublev(GL_MODELVIEW_MATRIX,Varptr MVMatrix[0])
		glGetDoublev(GL_PROJECTION_MATRIX,Varptr ProjMat[0])
		glGetIntegerv(GL_VIEWPORT,Varptr VPort[0])
		gluProject(EntityX(Entity),EntityY(Entity),EntityZ(Entity),MVMatrix,ProjMat,VPort, Varptr SX, Varptr SY, Varptr SZ)
		
		Return TVector.Create(SX, SY, SZ)

	
	End Method


Anyone?

I'm trying to do CameraProject for MiniB3D

CameraProject camera,x#,y#,z#
Parameters:
camera - camera handle
x# - world coordinate x
y# - world coordinate y
z# - world coordinate z


Strange, for me your method works (after changed to OO version as the compiler blocks because of object to int conversion beeing illegal).

But I'll do some other tests to see if it is only because of the setup of the basic entity test.

Hmm. No compiler errors here. (It's a method tho)
Although Y coordinate is everchanging, even though object is at center of screen.
A good guess is that some kind of projection is going on here.
Will investigate futher.

I edited the above post.
The projection issue is gone, was an error on my side!

Thats the code I used and put into the example after the other line of debugtext.
	Local vec:TVector = cam.ObjectToScreen(cube)
	DebugText 0,20, "Coords: " + vec.x + ","+vec.y+","+vec.z
	DebugText vec.x, height-vec.y, "Cube"  		' height - vec.y needed as OpenGL has reversed y. Else it looks like projection error!


Hmm. I tried that, but it didn't work. When are you calling ObjectToScreen? (Before/after renderworld etc.)
Also, mine is placed on a moving object.
It's correct that gluProject reverses the Y coordinate, since OpenGL starts at bottom left (weeeh, we've been smoking too much weed)

Can you make a very simple example that works for you?

patmaba - can you post an example program?

This program suggest MeshWidth/Height etc and CountSurfaces are working OK:

Import "../MiniB3D.bmx"

Local width=640,height=480,depth=16,mode=0

Graphics3D width,height,depth,mode

Local  cam=CreateCamera()
PositionEntity cam,0,0,-10

Local light=CreateLight(1)

Local tex=LoadTexture("media/test.png")

Local cube=CreateCube()

ScaleMesh cube,5,1,1

RenderWorld

DebugText 0,0,"MeshWidth: "+String(MeshWidth(cube))
DebugText 0,20,"Count Surfaces: "+String(CountSurfaces(cube))

Flip

WaitKey

ozak - Yeah I'll add Max2D support to the next version.

Btw: I'm working on the collision functions from Blitz3D and was wondering what the procedures are, if I should mail you a suggested update?

Hi Si,

I've also emailed some stuff you might find useful.

Yeah I'll add Max2D support to the next version.

Sweet! I was just starting to fiddle with straight OpenGL in order to find a better way to do 2D than using sprites childed to the camera (which led to the discovery of the sprite orientation issue you fixed so quickly!). This is a terrific tool. Thanks for your hard work!

I am still working on trying to get a camerapick to work but its proving to be pretty difficult.

Ozak:

I put your method on the TCamera class (think thats where you have it as well).

The code above was put into the basic example with the rotating cube etc straight after the other line of debug text so after renderworld ie about the last thing before the screen is flipped.

PS: For lazy programmers, here is the one with the correct y output. Just put it into the TCamera type.

' Object to Screen method
	Method ObjectToScreen:TVector(Entity:TEntity)
	
		Local SX:Double
		Local SY:Double
		Local SZ:Double
		Local MVMatrix:Double[16]
		Local ProjMat:Double[16]
		Local VPort:Int[4]
		glGetDoublev(GL_MODELVIEW_MATRIX,Varptr MVMatrix[0])
		glGetDoublev(GL_PROJECTION_MATRIX,Varptr ProjMat[0])
		glGetIntegerv(GL_VIEWPORT,Varptr VPort[0])
		gluProject(Entity.EntityX(),Entity.EntityY(),Entity.EntityZ(),MVMatrix,ProjMat,VPort, Varptr SX, Varptr SY, Varptr SZ)
		
		Return TVector.Create(SX, TGlobal.height - SY, SZ)

	
	End Method


And here is the whole test-privmitives.bmx, type based to make it work at all:

Import "../MiniB3D.bmx"

Local width=640,height=480,depth=16,mode=0

Graphics3D width,height,depth,mode

Local  cam:TCamera=CreateCamera()
PositionEntity cam,0,0,-10

Local light:TLight=CreateLight(1)

Local tex:TTexture=LoadTexture("media/test.png")

Local cube:TEntity=CreateCube()
Local sphere:TEntity=CreateSphere()
Local cylinder:TEntity=CreateCylinder()
Local cone:TEntity=CreateCone() 

PositionEntity cube,-6,0,0
PositionEntity sphere,-2,0,0
PositionEntity cylinder,2,0,0
PositionEntity cone,6,0,0

EntityTexture cube,tex
EntityTexture sphere,tex
EntityTexture cylinder,tex
EntityTexture cone,tex

Local cx#=0
Local cy#=0
Local cz#=0

Local pitch#=0
Local yaw#=0
Local roll#=0

' used by fps code
Local old_ms=MilliSecs()
Local renders
Local fps

While Not KeyDown(KEY_ESCAPE)		

	If KeyHit(KEY_ENTER) Then DebugStop

	' control camera

	If KeyDown(KEY_UP) Then cz#=cz#+1.0
	If KeyDown(KEY_LEFT) Then cx#=cx#-1.0
	If KeyDown(KEY_RIGHT) Then cx#=cx#+1.0
	If KeyDown(KEY_DOWN) Then cz#=cz#-1.0
	
	If KeyDown(KEY_W) Then pitch#=pitch#-1.0
	If KeyDown(KEY_A) Then yaw#=yaw#+1.0
	If KeyDown(KEY_S) Then pitch#=pitch#+1.0
	If KeyDown(KEY_D) Then yaw#=yaw#-1.0

	MoveEntity cam,cx#*0.5,cy#*0.5,cz#*0.5
	RotateEntity cam,pitch#,yaw#,roll#
	
	cx#=0
	cy#=0
	cz#=0

	'
	
	TurnEntity cube,0,1,0

	cx#=0
	cy#=0
	cz#=0

	RenderWorld
	renders=renders+1

	' calculate fps
	If MilliSecs()-old_ms>=1000
		old_ms=MilliSecs()
		fps=renders
		renders=0
	EndIf
	
	DebugText 0,0,"FPS: "+String(fps)
	Local vec:TVector = cam.ObjectToScreen(cube)
	DebugText 0,20, "Coords: " + vec.x + ","+vec.y+","+vec.z
	DebugText vec.x, vec.y, "Cube"  		

	Flip

Wend
End


The stuff I sent Si was some CameraPick and LinePick code I did for my own OGL engine. I'm just going through MiniB3D at the moment and looking at the viability of integrating it.

[EDIT]

It's failed. It works very well in my Engine, but is a bit of a 'square peg in a round hole' for MiniB3D. :(

Hi, my first post here: At first Simon, great work and I think with the help of this community this engine will be grow very fast.

Here is my addition i'm currently working on:

http://www.blitzforum.de/upload/file.php?id=451

It is a Terrain Engine (currently without LOD).
It should be in the end a Quadtree Terrain.

@Simon: Please add the UpdateNormals code from Mark, it is much faster here then yours. And for Terrains I need a good Updatenormals function.

Second Addition was a simply Wireframe command, but I think this is to small to post here ;)

Sent CameraProject to Simon. 100% like Blitz3D's.
Thanks to Dreamora for the help. I'll keep testing it tho.

This project is sweet! But I have one question.
Was unsure if I should start a new thread, or just ask away here. I hope nobody minds if I ask here. :)

I haven't used Blitz3D before so I don't know if this is possible to do this, but is there a way to make a mesh a child to a bone? One example is to place a weapon in the hand of a player or enemy.

I looked at the TMesh code, TBone code and the TKeys code but all I found was a function in TMesh that makes a copy of all the bones. And it didn't look like it was useful in this case.

Thanks for any help, and for working on MiniB3D!

In Blitz3D it isn't a problem.
As a Bone is an entity and any entity accepts child you can simply parent the object to the bone.

Haven't tried in MiniB3D yet.

How was this done in Blitz3D? I have been searching the code archives but haven't found anything that explains this.
Is the names for the bones saved in a B3D file?

EDIT:
Ooh, wait. There is a FindChild in TEntity. Looks like it could be useful in this case. :)

Yupp thats exactly the way it is done in B3D.
You load as AnimMesh and look for the bone by FindChild :)

I think I found a small bug with the lights.
The Blitz3D manual says: "Specifying a parent entity will still result in the light being created at position 0,0,0 rather than at the parent entity's position."
But when I added a light as a child to a robot in my little test-MiniB3D-game the light was placed at the feet.

The doc is wrong.

Strange
Because current B3D creates entities with specified parent at 0,0,0, but not global 0,0,0 but parent 0,0,0. Or is this just an inconsistency on lights?

It does not make sense to place it somewhere else than 0 of the parent as it will move relative to it and relative to "somewhere" is a little pointless.

Because current B3D creates entities with specified parent at 0,0,0, but not global 0,0,0 but parent 0,0,0

Yes, CreateCamera/Light/Mesh etc, when a parent is specified, will position the child entity at local 0,0,0 (i.e. the parent entity's position). This is true for all entities in either B3D or MiniB3D.

The docs suggest that the child entity is created at global 0,0,0 when a parent is specified, which is wrong.

In dep's case I would guess that the local 0,0,0 is at the robot's feet.

Well, I wanted it to be created at local 0,0,0. (at the feet of the robot.)
So it looks like there was no bug after all. Sweet. :)

Thanks.

Edit: A virtual cookie to the one who can guess what game I'm making a clone of, using MiniB3D. :)
Screenshot
(The zombie is a placeholder, will be removed later.)

[EDIT]
Oops.
[EDIT]
Well after some extensive testing I found out why why my LinePick / Camerapick stuff failed. All the Maths appear to be the reverse of my own OLG engine for some reason. :/

yeah isnt that the way blitz3d did it?

Well. You can join the club. My CameraProject only works with one camera :)

Maybe we should just add the needed math to code it all ourselves, instead of relying on Glu stuff (thinking of frustum culling here too)
That way we could have the orthogonal stuff too.

About my problem with the functions meshwidth, depth, height and count surface. The code work in a mini program.

The function work perfect with this code

Import "MiniB3D.bmx"

Graphics3D 800,600,16,2
m:TMesh=LoadMesh ("media/batfighter.b3d")
Print "CountSurfaces="+CountSurfaces(m)
Print "MeshWidth="+MeshWidth(m)
Print "MeshHeight="+MeshHeight(m)
Print "MeshDepth="+MeshDepth(m)
Print ""
Print "Press key to exit"

WaitKey


but in another program too big to post the result is incorrect

DebugLog:Entity XYZ CountSurfaces=0
DebugLog:Entity XYZ MeshWidth=-2.00000000e+009
DebugLog:Entity Base CountSurfaces=1
DebugLog:Entity Base MeshWidth=2.00000000

I havent found why

Email me the big program and I'll take a look.

Got some problems with adding children to bones.

Looks like (TMesh) children isn't placed at the parent position, and they isn't moved when the parent moves, and isn't rotated when the parent is rotating.

Here is a method from my Droid Type:
	Method New()
	
		If Not e_droid Then 
			' Load the mesh, then hide it. Used for making copies of this one later
			e_droid = LoadAnimMesh("data/droidmk2.b3d")
			HideEntity( e_droid )
		EndIf
		
		If Not e_sight Then
			e_sight = LoadMesh("data/lasersight.b3d")
			HideEntity( e_sight )
		EndIf

		obj = CopyEntity( e_droid )
		
		' Place the droid
		Local x:Int = 2 ' Use known values for debug reasons.
		Local z:Int = 3 
		PositionEntity( obj, 20+(x*40),0,20+(z*40) )
		RotateEntity( obj, 0, Rand(0,3)*90, 0 ) ' Get a random direction

		Local b:TEntity = FindChild( obj, "borglaserend" )
		If b Then
			lasersight = CopyEntity( e_sight,b )
			ShowEntity( lasersight )
			EntityFX( lasersight, 1 )
		
			Print EntityX(lasersight,True)+","+EntityY(lasersight,True)+","+EntityZ(lasersight,True)
		Else
			Print "Unable to find the bone!"		
		EndIf
		
	EndMethod


The debug output says:
-0.0206391700,13.4376907,0.975049317


And that looks like the correct position, if the origin is at the droid's feet. But the droid is placed at (global) 100,0,140. So, if I understand things correctly, the Output Should have said something like:
99.98, 13.437,140.975

Since I tell EntityX,Y,Z to return the global coordinates.

Or am I wrong here?

Yeah, looking into, bones don't actually transform child entities at the moment - need to fix that.

about countsurface and mesh size functions failed when Tmesh is used with loadanimmesh

here a code.

Import "MiniB3D.bmx"

Type TA
Field entity:TMesh

Method loadentity( pName:String )
entity = LoadAnimMesh( pName )
End Method
End Type

Graphics3D 800,600,16,2
m:TMesh=LoadMesh ("media/patmaba.b3d")
Print "CountSurfaces="+CountSurfaces(m)
Print "MeshWidth="+MeshWidth(m)
Print "MeshHeight="+MeshHeight(m)
Print "MeshDepth="+MeshDepth(m)
Print ""


A:TA = New TA
A.loadentity("media/patmaba.b3d")

Print "A CountSurfaces="+CountSurfaces(A.entity)
Print "A MeshWidth="+MeshWidth(A.entity)
Print "A MeshHeight="+MeshHeight(A.entity)
Print "A MeshDepth="+MeshDepth(A.entity)
Print "Press key to exit"

WaitKey

Quick question:

I'm working on a rudimentary collision detection and I'm having trouble with my terrain collisions. My terrain is a tilemapped series of meshes, so I'll need actual mesh collisions (rather than the bounding boxes I'm using for objects).

How are the values for each triangle/surface stored in the Tmesh type? Would I have to EachIn the surfaces of the mesh, then For-Next up to no_verts to get each of the vert coords (i.e. up to vert_coords[no_verts-1]) for each surface, with each vert_coords[i] representing either the x,y, or z value (relative to the mesh origin)? Are the vertexes themselves recorded in the array in clockwise order? Any help would be... er... helpful!

For vertices, you have one big array, with each vertex position stored like so: x (0), y (1), z (2), x (3), y (4), z (5) etc.

For triangles, you have another big array, with each vertex index stored like so: So: v2 (0), v1 (1), v0 (2), v2 (3), v1 (4), v0 (5) etc, with v0, v1, v2 representing the parameters in AddVertex.

So to get the vertex position for each triangle, you need to loop through the triangle array, get the vertex index, and use that to find the vertex position from the vertex array.

patmaba - your example runs OK here (I tested it with zombie.b3d). Can you send me your 'patmaba.b3d' model so I can test it with that?

Hi, again.
Here is small status on how far I was coming in the last days.

Terrain Engine mainly stays (some minor things and tweaking to get nearly to the original Terrain)
Also added Wireframe (not such a big thing)
and
If someone is interrested, I have succesfully attached Shaders to the Brushtype.

BtW, here is small demo of the Terrain:

http://klepto2.kl.funpic.de/DL/TerrainDemo.rar

Arrow Keys to Move around
Mouse to Look around
W for Wireframe
and Left Mouse Button for a small Shader test

Enjoy.

Link's dead.

Rightclick and save as :)

sorry, sometimes it works, sometimes not. But not long and I will have a better webspace. Currently follow sigi's post.

Seems to work well. What type of terrain system is it?

It is a preoptimised Tiled Quadtree Terrain.
It is mainly based on this code: http://www.blitzbasic.com/Community/posts.php?topic=34168#368818
and currently I try to embbed it into MiniB3D. The only thing I have vurrently a problem with, is to get the height of the real terrain.

Hmmm, unfortunately Eole released that code with a license agreement, so I'm not sure I'd be able to add it to MiniB3D.

To get the real height of the terrain use this:

ya#=(y10-y00)*fx+y00
yb#=(y11-y01)*fx+y01
y#=(yb-ya)*fz+ya
Where y00,y01,y10,y11 are the height of the tile corners, and fx# and fz# are the fractional x and z positional values (0-1) within the tile.

Well, I could make it new from scratch (now where I understand Quadtrees ;). and thx for the height formula, I will try it out.

From the license he added, there is nothing that prevents using it unless you are planning to make MiniB3D a commercial project.
But easiest thing is always to contact people and simply ask.

I'm currently porting Particle Candy to MiniB3D but need to add some commands before (I need TForm commands and Cam Project). When I'm done I'll send the code to its creator so he can decide if owners of the license get that code as well to use with MiniB3D.
I'm mainly interested in the speed difference we get because I'm quite sure that the BM-MiniB3D will be significantly faster.

What about games that use MiniB3D? Will the license prevent them from being commercial?

SimonH: I think this module deserves its own website and forum Where we can collect togethor on MiniB3d specifically.

I can't seend the model. I'm not the owner of the model.

But the model is exported with gile application( http://www.frecle.net/giles/ )

The problem come when i'm using LoadAnimMesh function.

Have you tried using TEntity for the type when using animmesh command on loading?
Main problem might be that Gile[s] head node has no geometry attached, it is only a pivot. so that might interfer perhaps.

Impossible Dreamora, the load function is implemented into TMesh.

Sorry missspelled the idea perhaps a little.
What I meant is that you assign the loaded animmesh to a TEntity instead of TMesh

But thinking over it there is another simple reason why it won't work with animmesh: exactly the reason above. You are asking the head node for its surfaces ... and as it is only a pivot, it naturally has none. Nor has it a mesh width as no geometry is attached. You have to ask all of its childs for this informations.
Although I'm not sure if B3D in this case just uppropagandated all the bounding box informations to get the dimensions on the head as well. In this case, at least the width, height, depth are bugged if they don't return anything on the head pivot. (bugged or might be added later. Currently culling is on sphere base not bounding volume and the later is the data, width - height - depth would return on the head pivot normally)

Yeah, if the head node is a pivot, that might cause CountSurface/MeshWidth etc to return wrong values. I'll look into it.

Dreamora: The TForm commands and CameraProject commands are already in the new version (0.3), which will be released soon. I'm not sure MB3D will be quicker yet though.

Glad to hear :)
We will see if it is faster or slower.

It would definitely be cool if it would be faster, as OpenGL is causing less problems than DX7 does, the newer the graphics driver are.

I have mailed Eole and I'm waiting for his answer now.

As long I'm currently working on GLSL Shader integration to the TBrush Type, which comes quite well.

My Terrain with a Environment Map Shader attached:



Here is some Code how to attach a Shader to the Brush:

Global Terrain:TTerrain = TTerrain.Create( "height2.png" , 4 , 5)
ScaleEntity Terrain.Terrain,40,40,40
Terrain.TextureTerrain(brush , 0.5 , 1)
'Terrain.TextureTerrain(detail , 0.01 , 0)
Terrain.PaintTerrain(brush1)


Global brush:TTexture = LoadTexture("media/sky_UP.bmp")
Local detail:TTexture = LoadTexture("CrackedStone.BMP")
Local brush1:TBrush = CreateBrush()
brush1.AddVertexShader("Shaders/CH10-envmap.vert.txt")
brush1.AddFragmentShader("Shaders/CH10-envmap.frag.txt") 

brush1.Po.Activate()
brush1.Po.SetUi1("EnvMap" , 1)
brush1.Po.SetUI3("BaseColor" , 0 , 0 , 150)
brush1.Po.SetUF1("MixRatio",.4)
brush1.Po.deActivate()


In the mainloop you could do a simply Terrain.setShader(True/False) to switch it on/off.

If V 0.3 is ready I will build it in and send the code to Simon.

You rock simon! So. Can we have 0.3 soon? Really need that Max2D stuff :)

Have I mentioned that this thing is getting better and better?

I might consider dropping my "2D entity framework" idea and instead thinking about a way of integrating my own particle system into MiniB3D (it has its root back in ParticleDreams for those that have used it when it was available. But got a major redesign to work more efficiently) as I definitely like it and would like to contribute to it as well :-)

I'm working on a multiplayer action game with the current MiniB3D and it's more than capable. Also, my game runs on both Windows and Mac without problems :)

yeah ill add to it, I am using this for my project as well.

thanks for the feedback about my problem. But have you a workaround with the gile exported model.

Currently the only workaround I could think if is:

Define minX,maxX / y / z:float
Define surfaces:int

Take your giles model and ask each child for its surface count and add that to surfaces
Ask each child for its width, depth, height, divide it by 2 and add it to entityX/y/z and see if it is larger / smaller than your minX / maxX etc and if so, apply it to the coresponding values.
As all the childs should be meshes (unless you exported lights as well), this shouldn't be a problem.

Ok DreamOra, but to ask my model, i must used the count surface function. Before to start this function have trouble with gile model.

Don't understand your posting.

Yes you must use the count surface function, but not on your model. You have to use the Entity Child functions to get all childs and ask those for the surfaces as those are the meshes.

When I'm back home and find time, I'll possibly write you a function to do so.

Anyone noticed that regular alpha blending does not work with sprites? Also, when using Max2D I always get additive alphablending no matter what I specify (even no blend)

Regards

Ozak

With Max2D this is expected. If you add alpha information, they are taken into account on anyblend beside SolidBlend (no blend does not exist, default is Mask when I remember correctly)

Haven't tested on sprites yet. But isn't that exactly what Blitz3D does as well?
If you want a different behavior with Blitz3D it is normally a mix of EntityBlend and TextureBlend to compensate each other.

I will just add my own pointless post to say that this project looks quite exciting.
Kudos Simon, and keep up the good work.

I have a calculation problem with my terrain system to get the current height at x,z.

Here is some code:
Method TerrainY:Float(x:Float , y:Float ,z:Float)
		Local Dist:Float = 99999999999
		Local Mesh:TMesh = GetMesh(x , z , Terrain.sx)
		PatchTest = Mesh
		Local ID:Int = 0
		Local Counter:Int = 0
		If Mesh = Null Then Return 0
				
		Local Vid:Int = 0
		Local surf:TSurface = Mesh.GetSurface(1)
			
		For Local I:Int = 0 To surf.CountTriangles() - 1
			Local VN:Int = surf.TriangleVertex(I,0)
			Local x1:Float = surf.VertexX(VN) + EntityX(mesh,True)
			Local y1:Float = (Surf.VertexY(VN) + 1 )+EntityY(mesh,True)
			Local z1:Float = surf.VertexZ(VN) + EntityZ(mesh,True)
			
			Local xd:Float = X1 - X
			Local yd:Float = y1 - y
			Local zd:Float = z1 - Z
			
			'Print "Local: " + surf.VertexZ(VN) + ":" + surf.VertexX(VN) + ":" + surf.VertexZ(VN)
			
				
			Local D:Float = Sqr(xd * xd + yd * yd + zd * zd)
			
			
			'Print D + " < " + Dist + " : " + I + " : " + Vid
			
			If D < Dist Then 
				Vid = I
				'ID = COunter
				Dist = D
			EndIf
			
		Next
		
		Local v1:Int = surf.TriangleVertex(Vid , 0)
		Local v2:Int = surf.TriangleVertex(Vid , 1) 
		Local v3:Int = surf.TriangleVertex(Vid , 2)
		
		
		TestID = V1
				
		Return PointHeightOnTri(x,z, surf.VertexX(v1),surf.VertexY(v1),surf.VertexZ(v1),surf.VertexX(v2),surf.VertexY(v2),surf.VertexZ(v2),surf.VertexX(v1),surf.VertexY(v3),surf.VertexZ(v3))
	End Method
Function PointHeightOnTri#(px#,pz#, x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#)
	Local e#=(x2-x1)*(z3-z1)-(x3-x1)*(z2-z1)
	e=1.0/e
	Local e1#=e*((x2-px)*(z3-pz)-(x3-px)*(z2-pz))
	Local e2#=e*((x3-px)*(z1-pz)-(x1-px)*(z3-pz))
	Local e3#=e*((x1-px)*(z2-pz)-(x2-px)*(z1-pz))
	Return e1*y1+e2*y2+e3*y3
End Function



As you see: the terrain is based an patches (equal to meshes)
so if i have found a mesh via the getmesh method (returns definatly the right Mesh) I'm going through all triangles in the surface and compare the dist to the given x ,y and z position.
Well I know that the VertexX commands returns local positions
and I have taken look to the TForm commands in B3D and added the needed things to the Vertexpositions.
Now I would guess that the triangle Id should change in a constant way, if I move across the terrain, but it doesn't. It jumps from one Id to another or stays on one Id a long time, any Ideas how to solve this?

thx.

Alrighty then...

After banging my head against Left Handed/Right Handed Matrices for a Looong time. I've made some working additions to the TMatrix Class. Just add in these methods:

Method MultiplyVector(I:TVector var, O:TVector Var)
	Local Mt:TMatrix = New TMatrix
	Local tmp:Float[3]
	Local tmp2:Float[3]
	Local itmp3:Float
	mt.LoadIdentity
	mt.Scale(1,1,-1)
	mt.Multiply(Self)
	itmp3 = 1.0 /(I.x*mt.grid[0,3]+I.y*mt.grid[1,3]+I.z*mt.grid[2,3]+mt.grid[3,3])
	tmp[0] = itmp3*I.x
	tmp[1] = itmp3*I.y
	tmp[2] = itmp3*(I.z*-1)
	O.x=tmp[0]*(mt.grid[0,0])+(tmp[1])*(mt.grid[1,0])+tmp[2]*(mt.grid[2,0])+itmp3*(mt.grid[3,0])
	O.y=tmp[0]*(mt.grid[0,1])+(tmp[1])*(mt.grid[1,1])+tmp[2]*(mt.grid[2,1])+itmp3*(mt.grid[3,1])
	O.z=tmp[0]*(mt.grid[0,2])+(tmp[1])*(mt.grid[1,2])+tmp[2]*(mt.grid[2,2])+itmp3*(mt.grid[3,2])
End Method

Method MultiplyNormal(I:TVector var, O:TVector Var)
	Local Mt:TMatrix = New TMatrix
	mt.LoadIdentity
	mt.Scale(1,1,-1)
	mt.Multiply(Self)
	Local tmp:Float[3]
	Local itmp:Float
	tmp[0]=I.x*mt.grid[0,0]+I.y*mt.grid[1,0]+(I.z*-1)*mt.grid[2,0]
	tmp[1]=I.x*mt.grid[0,1]+I.y*mt.grid[1,1]+(I.z*-1)*mt.grid[2,1]
	tmp[2]=I.x*mt.grid[0,2]+I.y*mt.grid[1,2]+(I.z*-1)*mt.grid[2,2]
	itmp=1.0/sqr(tmp[0]*tmp[0]+tmp[1]*tmp[1]+tmp[2]*tmp[2])
	O.x=tmp[0]*itmp
	O.y=tmp[1]*itmp
	O.z=tmp[2]*itmp
End Method
Method Invert:TMatrix() ' Returns an Inverted Matrix
  Local out:TMatrix = New TMatrix
  Adjoint(out)
  Return out
End Method
Method Adjoint( out:TMatrix Var )
  out.grid[0,0]  =   det3x3(grid[1,1], grid[2,1], grid[3,1], grid[1,2], grid[2,2], grid[3,2], grid[1,3], grid[2,3], grid[3,3])
  out.grid[1,0]  = - det3x3(grid[1,0], grid[2,0], grid[3,0], grid[1,2], grid[2,2], grid[3,2], grid[1,3], grid[2,3], grid[3,3])
  out.grid[2,0]  =   det3x3(grid[1,0], grid[2,0], grid[3,0], grid[1,1], grid[2,1], grid[3,1], grid[1,3], grid[2,3], grid[3,3])
  out.grid[3,0]  = - det3x3(grid[1,0], grid[2,0], grid[3,0], grid[1,1], grid[2,1], grid[3,1], grid[1,2], grid[2,2], grid[3,2])

  out.grid[0,1]  = - det3x3( grid[0,1], grid[2,1], grid[3,1], grid[0,2], grid[2,2], grid[3,2], grid[0,3], grid[2,3], grid[3,3])
  out.grid[1,1]  =   det3x3( grid[0,0], grid[2,0], grid[3,0], grid[0,2], grid[2,2], grid[3,2], grid[0,3], grid[2,3], grid[3,3])
  out.grid[2,1]  = - det3x3( grid[0,0], grid[2,0], grid[3,0], grid[0,1], grid[2,1], grid[3,1], grid[0,3], grid[2,3], grid[3,3])
  out.grid[3,1]  =   det3x3( grid[0,0], grid[2,0], grid[3,0], grid[0,1], grid[2,1], grid[3,1], grid[0,2], grid[2,2], grid[3,2])

  out.grid[0,2]  =   det3x3( grid[0,1], grid[1,1], grid[3,1], grid[0,2], grid[1,2], grid[3,2], grid[0,3], grid[1,3], grid[3,3])
  out.grid[1,2]  = - det3x3( grid[0,0], grid[1,0], grid[3,0], grid[0,2], grid[1,2], grid[3,2], grid[0,3], grid[1,3], grid[3,3])
  out.grid[2,2]  =   det3x3( grid[0,0], grid[1,0], grid[3,0], grid[0,1], grid[1,1], grid[3,1], grid[0,3], grid[1,3], grid[3,3])
  out.grid[3,2]  = - det3x3( grid[0,0], grid[1,0], grid[3,0], grid[0,1], grid[1,1], grid[3,1], grid[0,2], grid[1,2], grid[3,2])
  
  out.grid[0,3]  = - det3x3( grid[0,1], grid[1,1], grid[2,1], grid[0,2], grid[1,2], grid[2,2], grid[0,3], grid[1,3], grid[2,3])
  out.grid[1,3]  =   det3x3( grid[0,0], grid[1,0], grid[2,0], grid[0,2], grid[1,2], grid[2,2], grid[0,3], grid[1,3], grid[2,3])
  out.grid[2,3]  = - det3x3( grid[0,0], grid[1,0], grid[2,0], grid[0,1], grid[1,1], grid[2,1], grid[0,3], grid[1,3], grid[2,3])
  out.grid[3,3]  =   det3x3( grid[0,0], grid[1,0], grid[2,0], grid[0,1], grid[1,1], grid[2,1], grid[0,2], grid[1,2], grid[2,2])
EndMethod
Function det3x3!( a1!, a2!, a3!, b1!, b2!, b3!, c1!, c2!, c3! )
  Local ans!
  ans = a1 * det2x2( b2, b3, c2, c3 )
  ans = ans - b1 * det2x2( a2, a3, c2, c3 )
  ans = ans + c1 * det2x2( a2, a3, b2, b3 )
  Return ans
End Function
Function det2x2!( a!, b!, c!, d!)
  Return a*d-b*c
End Function


This will allow you to convert normals and vectors by an arbitrary matrix and to invert the matrix to do the opposite.

Example Program using the above to track the movement and rotation of a cube, shown by spheres.

' Based on code by Birdie and Peter Scheutz

Import "../MiniB3D.bmx"

SetGraphicsDriver GLGraphicsDriver(),GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER

Global ax#, ay#,tim#

Local w:TGadget = CreateWindow("MiniB3D in a GUI window", 10, 10, 512, 512 )

Local c:TGadget = CreateCanvas(0,0,ClientWidth(w),ClientHeight(w),w,0)
SetGadgetLayout c,1,1,1,1

TGlobal.width = ClientWidth(w)
TGlobal.height = ClientHeight(w)

TGlobal.depth=16
TGlobal.mode=0
TGlobal.rate=60

SetGraphics CanvasGraphics( c )
ActivateGadget c
TGlobal.GraphicsInit()

Local cam:TCamera=CreateCamera()
PositionEntity cam,0,0,-10

Local light:TLight=CreateLight(1)

Local tex:TTexture=LoadTexture("media/test.png")

Local cube:TMesh=CreateCube()
Local sphere:TMesh=CreateSphere()
Local Cone:TMesh = CreateSphere()
Local Cube2:TMesh = Createsphere()

PositionEntity cube,0,0,0
PositionEntity sphere,0,0,0
PositionEntity Cone,0,0,0
PositionEntity Cube2,0,0,0

EntityTexture cube,tex
EntityTexture sphere,tex
EntityColor cone,255,0,0
EntityColor Cube2,0,255,0

Local cx#=0
Local cy#=0
Local cz#=0
Local tog

Local pitch#=0
Local yaw#=0
Local roll#=0

' used by fps code
Local old_ms:Int=MilliSecs()
Local renders:Int
Local fps:Int

Local up_key:Int
Local down_key:Int
Local left_key:Int
Local right_key:Int

CreateTimer( 60 )
camerazoom cam,3
While True

	WaitEvent()

	Select EventID()

		Case EVENT_KEYDOWN
		
			Select EventData()
				Case KEY_ESCAPE
					End
				Case KEY_UP
					up_key = True
				Case KEY_DOWN
					down_key = True			
				Case KEY_LEFT
					left_key = True
				Case KEY_RIGHT
					right_key = True	
				Case KEY_A
					A_KEY = True
				Case KEY_Z
					z_KEY = True		
			EndSelect
			
		Case EVENT_KEYUP
		
			Select EventData()
				Case KEY_UP
					up_key = False
				Case KEY_DOWN
					down_key = False			
				Case KEY_LEFT
					left_key = False
				Case KEY_RIGHT
					right_key = False
				Case KEY_A
					A_KEY = False
				Case KEY_Z
					z_KEY = False		
			EndSelect

		Case EVENT_WINDOWCLOSE
		
            End

		Case EVENT_WINDOWSIZE
		
			TGlobal.width = ClientWidth(w)
			TGlobal.height = ClientHeight(w)

			cam.CameraViewport(0,0,ClientWidth(w),ClientHeight(w))
							
			DebugLog "EVENT_WINDOWSIZE" 

		Case EVENT_TIMERTICK

			If up_key Then cy#=cy#+0.1
			If left_key Then cx#=cx#-0.1
			If right_key Then cx#=cx#+0.1
			If down_key Then cy#=cy#-0.1
			
			If a_key Then cz#=cz#+0.1
			If z_key Then cz#=cz#-0.1

			positionentity cube,cx#,cy#,cz#
			RotateEntity cam,pitch#,yaw#,roll#
			
			RedrawGadget c
              
		Case EVENT_GADGETPAINT
			
			SetGraphics CanvasGraphics( c )

			TurnEntity cube,1,1,1
			
			Local Inv:TMatrix 
		
			Local Vec1:TVector = New TVector
			Local Vec2:TVector = New TVector
			Local Vec3:TVector = New TVector
		
			Vec1.z = -2 ; vec1.y = 0 ; vec1.x = 0
			Vec2.z = 0 ; vec2.y = 2 ; vec2.x = 0
			Vec3.z = 0 ; vec3.y = 0 ; vec3.x = 2
		
			Cube.mat.MultiplyVector(Vec1,vec1)
			Cube.mat.MultiplyVector(Vec2,vec2)
			Cube.mat.MultiplyVector(Vec3,vec3)

			'Inv = Cube.mat.Invert()			

			'inv.MultiplyVector(Vec1,vec1)
			'inv.MultiplyVector(Vec2,vec2)
			'inv.MultiplyVector(Vec3,vec3)
					
			positionentity sphere,vec1.x,vec1.y,vec1.z
			positionentity cone,vec2.x,vec2.y,vec2.z
			positionentity cube2,vec3.x,vec3.y,vec3.z

			RenderWorld
			Flip True
	EndSelect
Wend


Looks like this:


Amazing work everyone - this is truly the best BlitzMax community project anyone could ask for. I wish I had the 3d and math knowledge to contribute. You guys rock. :)

Just to let you know, I will probably opt against adding stuff like terrain systems, shader systems, bsps, md2s etc to the main release of MiniB3D. While the support and interest that MiniB3D is gained is quite overwhelming, there a couple of things which I need to make clear:

* While I am a member of BRL I cannot allow MiniB3D to become a conflict of interest with either B3D or Max3D, and therefore MiniB3D will remain exactly that - a lightweight version of B3D without all the bells and whistles. There are a few commands left that I wish to add (most of which will be forthcoming in the next release), but after than, I will consider MiniB3D to be pretty much 'done' (bar optimisations and bug fixes).

* MiniB3D is being written so that I can convert Super Gerball to the Mac. MiniB3D does not make me any money, Super Gerball does. Therefore really I cannot afford to devote more time to MiniB3D than is necessary, and while I would dearly like to spend all day attending to support issues and managing all the different author contributions, unfortunately my day job and other commitments dictate that I can't.

I hope you understand. Just felt the need to post this as I felt MiniB3D was spiralling out of control somewhat, and I haven't really got the time to contribute to this thread or project as much as I would like. I can promise though that I will continue to support and maintain MiniB3D as much as I can - my own game projects depend on it (at least until Mark releases his own GL B3D), so it won't be abandoned anytime soon.

Of course, people are still free to release their own add-ons and libs, so hopefully this won't affect anything too much. I just wanted to clarify that MiniB3D itself will not be developed much further.

ouch must be Blitz Research slapped your hand :(

well I hope as a community we will keep this going strong.

Don't see any conflict with Max3D. Max3D isn't targeted at the same market.

Nor is Blitz3D as it bases on an API not fully supported anymore by current graphic card drivers. (I'm getting more and more confusing issues on NV side).

but yes, I understand that you have a real life, like we all do have it :-)
But after all, it would be sad if the only BM based 3D engine would die, so I hope you won't go against people creating addon modules/sources for it to extend its possibilities.

SimonH;
Perhaps, when you feel MiniB3D to be as complete as you want it to be, post it as a community project?
I think all the effort you put into it could be a very good base for others to expand on.. :)

From Mark's Worklog:
I am also designing Max3D with older hardware somewhat in mind, but any such version - if it ever actually happens - will have *less* capabilities than Blitz3D. Which oddly enough increases the chance of a GL Blitz3D happening one day - unless Si H's MiniB3D gets there first!



In all honesty, most of the Blitz community are waiting for Max3D before they start any real serious 3D work (I am). I already wrote a Mini 3D Engine that does some very similar things, but is certainly not as well/clearly written as MiniB3D (in my defence, I wrote it purely as a learning experience :)

I think that to get the most out of Max3D, it is good to play about with other Blitz written engines. Not only is it a good learning experience, It also helps us to see how these things are not trivial to write!

When Max3D does get out there, we'll see it for the cool stuff it's going to be. That's been my motivation for chipping in. It wouldn't occur to me to think that any 3D Engine I am likely to write/contribute to could be competing with Max3D.

Max3D is cutting edge. B3D is old.

Both are very good things to be, for completely different reasons. There is no competition whatsoever with each other from what I can tell.

When MiniB3D reaches 'complete' as far as you're concerned simon... I think it would be a very wise idea for either you to create a Sourceforge page and hand control over to someone else, or BRL to take it up and offer it alongside Max3D.

If BRL would be so kind to recognize the overwhelming resonance to MiniB3D (to me its more attractive than the announced Max3D stuff) - why don't they make it fully and officially to a product of them ? Should this not be possible with a product started by one members of their team ?? They might call it "Blitz 3D Next Generation" and I gladly would pay some money for it, if its Version 1.0 supports 2D graphics too.

Don't use the 3d side of things myself, but certainly the benefit of this project is getting existing Blitz3d projects into BlitzMax (almost better than a code converter tool).

I would not have thought it should/would be seen as a conflict to continue the module as it's a great way to bring people over to BlitzMax!

Much in the same way you might convert VB6 into VB.Net, in the end you will (eventually) either re-write it to take advantage of new features/functionality in the advanced product or start your new projects in BlitzMax.

Simon has done a great job and should be congratulated!!

Just to let you know, I will probably opt against adding stuff like terrain systems, shader systems, bsps, md2s etc to the main release of MiniB3D.


Sounds perfect. My intrest is in a "low end" 3D Engine, and MiniB3D fits the bill perfectly. I think the main thing to add is hardware checks and switches, that'll let it run on low end GFX cards. This is one of the true strenghs of the Blitz3D engine.

I'm really hoping that the any addition of shaders and such, *if they are made*, will be made as optional modules or at least as features that can be turned on and off.

There is also the possibillity to fork the project into a lowend and a highend version. Personally I think that if you want a high end 3D engine, you should go with one of the existing ones or wait for Max3D, but that's just me... ;)

PS: Thanks Terrabit, that matrix stuff works ace!

PPS: I have deployed a BMax OpenGL application on a number of lowend computers last year, and it is went rather well: 9 out of 10 would run the basic stuff though some did need a GFX card driver update.

I don't see why this isn't bundle with the BlitzMax install. I see MiniB3D as an advantage to Max not as compatition to B3D. BRL should actively encourage Simon to complete it. But whatever happens I don't think the project should stray from it's original goal of working exactly as B3D does. I feel it's this clearly defined goal that has kept, and will keep, the project on track. If everyone is pulling in the same direction we'll get there quicker.

I don't think that anyone is planning to change the way the core is working, even in cases where B3D worked against a usefull behavior that then had to be faked again.

ouch must be Blitz Research slapped your hand :(

Not at all - in fact the opposite. Mark has helped with various things and gave his full support to the public release. The decision on how far to take MiniB3D is mine alone.

Don't see any conflict with Max3D. Max3D isn't targeted at the same market.

It doesn't conflict at the moment, if however shaders and particle systems were added to MiniB3D, then it starts edging into Max3D territory.

Nor is Blitz3D

If MiniB3D has more and more features added to it, then MiniB3D becomes MassiveB3D, and Blitz3D becomes MiniBlitz3D. Do you see?

But after all, it would be sad if the only BM based 3D engine would die

It wouldn't die, it would be finished - nothing more to add to it.

Sounds perfect. My intrest is in a "low end" 3D Engine, and MiniB3D fits the bill perfectly. I think the main thing to add is hardware checks and switches, that'll let it run on low end GFX cards

At last, someone on the same wavelength as me.

I agree with simons decision. After all, we got the source so we can add specific features we need.

We just need those picking/collision funcs :)

I agree MiniB3D should not add any more than what B3D has, but I think everything simon gave examples of
I will probably opt against adding stuff like terrain systems, shader systems, bsps, md2s etc to the main release of MiniB3D.

with the exception of shaders, should eventually see it in by somebody...

As I have written, I'm having Shaders already build in with MiniB3D, I'm not really satisfied how it is currently build into the engine so I have some Questions. Currently the Shader is build in TBrush, but this I have found out isn't a good solution because it is hard to handle if there is no shader, and you want just use standard textures. So I ask you what do you think of this idea:

I will start a TShader type which has a second set of textures
applied to itself. This Shader Type will be handled like TBrush without the whole blend modes etc. . And in the Program you only have to assign the textures used by the shader to the TShader class and could keep the TBrush as a Fallback, if there is no Shader available.

PS: I completely understand you Simon. I think addons could be handled like usermade libs for B3D, so you everyone is able to choose self what he wants in MiniB3D. So thx for this great expandable Engine.

Wouldn't a TShader as an extended TBrush make more sense, at least from the point of handling it as an addon to MiniB3D?
I don't know how you actually integrated it so this could be an extremely worse idea as well.
Just seemed like a good idea to me as you can change the default brush behavior to fit your shader behavior without needing to change / break with other stuff.

Hi

First time I hear about minib3d

seem nice, I wonder why not add feature close to blitz3d
since I own B3D the only avantage would be speed probaly and have hability to compile to other platform, I wonder if Blitz Research today still make money of blitz3d since most of people here wait for max3d, for my point I will never get back to b3d because bmax offer much more possibility that Blitzbasic don't have.

by the way great work simon. :)

Just downloaded 0.27. Is it just me or did CopyMesh() get broken? My code works just fine in 0.26, but in 0.27 the copied mesh is inside out.

dear simonh,

can you please add a collision detection routine.

I don't know how to add a collision sytem like linepick.

But, i have found a doc about sphere tree collision detection

the url of the topic is
http://isg.cs.tcd.ie/spheretree/#examples


I'm starting a building spheretree, but the first step is hard

update the value of the to constant :
LE_MESH is the path of your mesh
LA_PROFONDEUR is the deep of the spheretree.


' =================
' Author patmaba
' patmaba@...
' =================

SuperStrict 
Import "MiniB3D.bmx"
Import "3DMathLib20.bmx"

Const LE_MESH:String = "media\batfighter\Batfighter.b3d"
'Const LE_MESH:String = "media\navette.b3d"
'Const LE_MESH:String = "media\patmaba.b3d"
'Profondeur toujours >=  1
Const LA_PROFONDEUR:Int = 4

' -----------------------
' Variable(s) globale(s)
' -----------------------
Global cam:TCamera
Global D:TMesh
Global Light1:TLight
Global m:TMesh
Global gi_CubeSize:Float = 0.0

'------------------------
'Freelook cam Var
'------------------------
Global Mouse_X_Speed:Float 
Global Mouse_Y_Speed:Float 
Global Camera_VelX:Float 
Global Camera_VelZ:Float 
Global Camera_Pitch:Float 
Global Camera_Yaw:Float 
Global oldmx:Int 
Global oldmy:Int


Const AppFPS:Int = 50
Global FramePeriod:Int = 1000 / AppFPS
Global FrameTime:Int = MilliSecs () - FramePeriod
Global FrameElapsed:Int 
Global FrameTicks:Int 
Global FrameTween:Float 

' ---------------
' Init la scene
' ---------------
InitScene()


' ---------------
' Init les Agents
' ---------------
InitOctree()


' -------------------------------------
' Variables pour la gestion du fps
' -------------------------------------
Local old_ms:Int=MilliSecs()
Local renders:Int
Local fps:Int 

Global countbox:Int=0

Repeat
	' --------------------------
	' Frame rate limiting
	' --------------------------
	Repeat
		FrameElapsed = MilliSecs () - FrameTime
	Until FrameElapsed

	FrameTicks = FrameElapsed / FramePeriod
	FrameTween:Float = Float (FrameElapsed mod FramePeriod) / Float (FramePeriod)

	' -----------------------
	' Update tweening
	' -----------------------
	For Local FrameLimit:Int = 1 To FrameTicks

		FrameTime = FrameTime + FramePeriod
		
		UpdateGame ()
		UpdateWorld
	Next

	' -------------------
	' Redraw world
	' -------------------
	RenderWorld 
	
	' ---------------------
	' Text
	' ---------------------
	
	cube( -MeshWidth(m)/2,MeshWidth(m)/2,-MeshHeight(m)/2, MeshHeight(m)/2,-MeshDepth(m)/2,MeshDepth(m)/2)
	Flip False	
Until KeyHit (KEY_ESCAPE)


Function UpdateGame()
	Proc_Freelook(1.03,0.03)		
	PointEntity cam, m	
EndFunction 



' ---------------------------------
' InitScene() 
' Description de la scene 
' ---------------------------------
Function InitScene()
	Graphics3D 800,600,32,0

	' -------------------------------------
	' Setup camera 
	' -------------------------------------
	cam=CreateCamera()
	PositionEntity cam,-11,70,-125
	CameraRange cam,1,250000
	CameraZoom cam,0.9

	' -------------------------------------
	' Setup Light and ambiance
	' -------------------------------------
	Light1=CreateLight(2)
	PositionEntity Light1,-1630,1630,1630
	LightColor Light1,155,220,255
	LightRange Light1,5500


EndFunction 



' ---------------------------------
' InitOctree() 
' Calcul la taille de mon octree sur base du mache augmenté 
' de 15%( * 1.15)
' ---------------------------------
Function InitOctree()
	m:TMesh = LoadMesh(LE_MESH)		
	gi_CubeSize = 0.0
	
	gi_CubeSize = MeshWidth( m )	
	If gi_CubeSize < MeshHeight( m ) Then gi_CubeSize = MeshHeight( m )
	If gi_CubeSize < MeshDepth( m ) Then gi_CubeSize = MeshDepth( m )	
	gi_CubeSize = gi_CubeSize * 1.15
	
	PositionEntity cam,-gi_CubeSize /2,gi_CubeSize /2,-gi_CubeSize /2
	PointEntity cam, m
	
	dessine_octree()		

	DebugLog "countbox="+countbox
End Function 



'------------------------
'Camera freelook
'------------------------
Function Proc_Freelook(Velocity:Float,Speed:Float)
	Local flag:Int=False 
	
	Mouse_X_Speed=(MouseXSpeed())*0.5
	Mouse_Y_Speed=(MouseYSpeed())*0.5

	MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
	Camera_Pitch=Camera_Pitch+Mouse_Y_Speed
	Camera_Yaw=Camera_Yaw+Mouse_X_Speed

	If flag=True
		RotateEntity cam,Camera_Pitch,-Camera_Yaw,0
	EndIf 
	
	If KeyDown(KEY_LEFT) Then
		Camera_VelX=Camera_VelX-Speed
	ElseIf  KeyDown(KEY_RIGHT)
		Camera_VelX=Camera_VelX+Speed
	EndIf
	
	If KeyDown(KEY_DOWN) Then
		Camera_VelZ=Camera_VelZ-Speed
	ElseIf  KeyDown(KEY_UP)
		Camera_VelZ=Camera_VelZ+Speed
	EndIf
 
	Camera_VelX=Camera_VelX/Velocity
	Camera_VelZ=Camera_VelZ/Velocity
	MoveEntity cam,Camera_VelX,0,Camera_VelZ

	If KeyDown(KEY_UP) Then
		MoveEntity cam,0,0,Speed
	EndIf

	If KeyDown(KEY_DOWN) Then
		MoveEntity cam,0,0,-Speed
	EndIf

	If KeyDown(KEY_RIGHT) Then
		MoveEntity cam,Speed,0,0
	EndIf

	If KeyDown(KEY_LEFT) Then
		MoveEntity cam,-Speed,0,0
	EndIf
End Function

Function MouseXSpeed:Int()
	Local mxs:Int=MouseX()-oldmx
	oldmx=MouseX()
	Return mxs
End Function

Function MouseYSpeed:Int()
	Local mys:Int=MouseY()-oldmy
	oldmy=MouseY()
	Return mys
End Function


'------------------------
'dessine un cube en mode de file de fer
'------------------------
Function cube (x0:Float, x1:Float, y0:Float, y1:Float, z0:Float, z1:Float)
	glBegin (GL_LINE_STRIP);

	glVertex3f (x0, y0, z0);
	glVertex3f (x1, y0, z0);
	glVertex3f (x1, y1, z0);
	glVertex3f (x0, y1, z0);
	glVertex3f (x0, y0, z0);
	glVertex3f (x0, y0, z1);
	glVertex3f (x1, y0, z1);
	glVertex3f (x1, y0, z0);
	glVertex3f (x1, y0, z1);
	glVertex3f (x1, y1, z1);
	glVertex3f (x1, y1, z0);
	glVertex3f (x1, y1, z1);
	glVertex3f (x0, y1, z1);
	glVertex3f (x0, y1, z0);
	glVertex3f (x0, y1, z1);
	glVertex3f (x0, y0, z1);

	glEnd ();

EndFunction 

' dessine l'octree recursivement
Function dessine_8_cubes (lxmin:Float, lxmax:Float, lymin:Float, lymax:Float, lzmin:Float, lzmax:Float, pMaxLevel:Int, pCurrentLevel:Int, the_list:TList)

	Local lb_val:Int
	Local l_vsomme:Vector = Vector.Create()
	Local l_vmin:Vector = Vector.Create()
	Local l_vmax:Vector = Vector.Create()
	
	'lb_val:Int = Point_Inside_Box(m, lxmin, lxmax, lymin, lymax, lzmin, lzmax )
	Local my_list:TList = Point_Inside_List(lxmin, lxmax, lymin, lymax, lzmin, lzmax, the_list )
	
	If my_list.count() = 0
		lb_val = False
	Else 	
		lb_val = True
	EndIf 
	' si on est un noeud terminal on s'arrete 
	If (pMaxLevel=pCurrentLevel) 'and ( lb_val = True)

		l_vsomme.Set(0,0,0)
		DebugLog "pCurrentLevel="+pCurrentLevel
		For Local L:TVertexInfo = EachIn my_list
			Local Surface_Handle:TSurface = GetSurface(m, L.SurfIndex)
			Local vx:Float = VertexX#(Surface_Handle, L.VertIndex)			
			Local vy:Float = VertexY#(Surface_Handle, L.VertIndex)			
			Local vz:Float = VertexZ#(Surface_Handle, L.VertIndex)				

			l_vsomme.x = l_vsomme.x + vx 
			l_vsomme.y = l_vsomme.y + vy 
			l_vsomme.z = l_vsomme.z + vz 
			
			If vx < l_vmin.x Then l_vmin.x = vx
			If vy < l_vmin.y Then l_vmin.y = vy			
			If vz < l_vmin.z Then l_vmin.z = vz						
			If vx > l_vmax.x Then l_vmax.x = vx
			If vy > l_vmax.y Then l_vmax.y = vy			
			If vz > l_vmax.z Then l_vmax.z = vz						
			'DebugLog "<" + vx + "," + vy + "," + vz + ">"
		Next 
		l_vsomme.DivS(my_list.count())				

'       Vieu code pour un sphere tree       
'
'		Local c:TMesh = CreateCube()		
'		EntityAlpha c, 0.4
'		PositionEntity c, (lxmin + lxmax) / 2,(lymin + lymax) / 2,(lzmin + lzmax) / 2
'		ScaleEntity c, 1/MeshWidth(c)*(lxmax-lxmin),  1/MeshHeight(c)*(lymax-lymin), 1/MeshDepth(c)*(lzmax-lzmin)		

'		Local s:TMesh = CreateSphere()		
'		EntityAlpha s, 0.4

		Local px:Float=( (l_vmin.x + l_vmax.x) / 2 )
		Local py:Float=( (l_vmin.y + l_vmax.y) / 2 )
		Local pz:Float=( (l_vmin.z + l_vmax.z) / 2 )

		'PositionEntity s, (lxmin + lxmax) / 2,(lymin + lymax) / 2,(lzmin + lzmax) / 2
'		PositionEntity s, px,py,pz
		
		Local l_rayon:Float = (l_vmin.Magnitude() + l_vmax.Magnitude())/2
		Local si:TSphereInfo = TSphereInfo.Create(px, py, pz, l_rayon)
		countbox=countbox+1
		Return
	EndIf 
	
	If lb_val= True and lb_val
	' on rappelle rcursivement pour les 8 fils
	dessine_8_cubes (lxmin, (lxmin + lxmax) / 2, lymin, (lymin + lymax) / 2, lzmin, (lzmin + lzmax) / 2, pMaxLevel, pCurrentLevel + 1, my_list )
	dessine_8_cubes (lxmin, (lxmin + lxmax) / 2, lymin, (lymin + lymax) / 2, (lzmin + lzmax) / 2, lzmax, pMaxLevel, pCurrentLevel + 1, my_list )

	dessine_8_cubes (lxmin, (lxmin + lxmax) / 2, (lymin + lymax) / 2, lymax, lzmin, (lzmin + lzmax) / 2, pMaxLevel, pCurrentLevel + 1, my_list )
	dessine_8_cubes (lxmin, (lxmin + lxmax) / 2, (lymin + lymax) / 2, lymax, (lzmin + lzmax) / 2, lzmax, pMaxLevel, pCurrentLevel + 1, my_list )

	dessine_8_cubes ((lxmin + lxmax) / 2, lxmax, lymin, (lymin + lymax) / 2, lzmin, (lzmin + lzmax) / 2, pMaxLevel, pCurrentLevel + 1, my_list )
	dessine_8_cubes ((lxmin + lxmax) / 2, lxmax, lymin, (lymin + lymax) / 2, (lzmin + lzmax) / 2, lzmax, pMaxLevel, pCurrentLevel + 1, my_list )

	dessine_8_cubes ((lxmin + lxmax) / 2, lxmax, (lymin + lymax) / 2, lymax, lzmin, (lzmin + lzmax) / 2, pMaxLevel, pCurrentLevel + 1, my_list )
	dessine_8_cubes ((lxmin + lxmax) / 2, lxmax, (lymin + lymax) / 2, lymax, (lzmin + lzmax) / 2, lzmax, pMaxLevel, pCurrentLevel + 1, my_list )
	EndIf 
EndFunction 



Function dessine_octree ()
	Local my_list:TList 
	my_list = New TList
	
	glDisable (GL_TEXTURE_2D);
	glColor3ub (50, 255, 50);
	my_list = GetPointIntoList(m)
	dessine_8_cubes (-(gi_CubeSize/2), (gi_CubeSize/2), -(gi_CubeSize/2), (gi_CubeSize/2), -(gi_CubeSize/2), (gi_CubeSize/2),LA_PROFONDEUR, 1, my_list)	
	glColor3ub (255, 255, 255);
	glEnable (GL_TEXTURE_2D);
	
	TSphereInfo.p_delSphereIntoSphere()
	DebugLog "Nombre de sphere :" + TSphereInfo.TAllList.count()
EndFunction



Type TVertexInfo
	Field SurfIndex:Int
	Field VertIndex:Int
EndType 



Function GetPointIntoList:TList(ThisEntity:TMesh )		

	' Calculate the bounding box (in Object space) For this Object.
	' You can precalculate this For every Object in your game For a huge speed increase!
	Local Surfaces:Int = CountSurfaces(ThisEntity)
	Local my_list:TList = New TList
	Local t:Int=0
	For Local LOOP_Surface:Int = 1 To Surfaces
		Local Surface_Handle:TSurface = GetSurface(ThisEntity, LOOP_Surface)	
		Local Verts:Int = CountVertices(Surface_Handle) - 1
		For Local LOOP_Verts:Int = 0 To Verts-1			
			Local my_vi:TVertexInfo = New TVertexInfo
			my_vi.SurfIndex = LOOP_Surface
			my_vi.VertIndex = Loop_Verts
			my_list.AddLast my_vi
		Next
	Next
		
	Return my_list
EndFunction



Function Point_Inside_List:TList( min_x:Float, max_x:Float, min_y:Float, max_y:Float, min_z:Float, max_z:Float, thelist:TList )		
	
	Local my_list:TList = New TList	

	For Local L:TVertexInfo = EachIn thelist
		Local Surface_Handle:TSurface = GetSurface(m, L.SurfIndex)
		Local vx:Float = VertexX#(Surface_Handle, L.VertIndex)			
		Local vy:Float = VertexY#(Surface_Handle, L.VertIndex)			
		Local Vz:Float = VertexZ#(Surface_Handle, L.VertIndex)				

		' Determine If the point (in Object space) is inside the bounding box (in Object space).
		If (vx# > min_x#) and (vx# < max_x#) and (vy# > min_y#) and (vy# < max_y#) and (Vz# > min_z#) and (vz# < max_z#)				
			Local my_vi:TVertexInfo = New TVertexInfo
			my_vi.SurfIndex = L.SurfIndex
			my_vi.VertIndex = L.VertIndex
			my_list.AddLast my_vi
		EndIf 
	Next 
	
	Return my_list
EndFunction



Type TSphereInfo
	Field Entity:TMesh
	Field vPos:Vector
	Field rayon:Float

	' ---------------------------------
	' Creation d'une liste pour le type
	' ---------------------------------
	Global TAllList:TList

	Method New ()
       	If TAllList = Null Then TAllList = New TList
       	TAllList.AddLast Self
    EndMethod 

	Function Create:TSphereInfo(px:Float, py:Float, pz:Float, pr:Float)
		Local S:TSphereInfo = New TSphereInfo
		
		S.vPos = Vector.Create()
		S.vPos.Set( px, py, pz )
			
		S.Entity = CreateSphere(8)	  
		EntityAlpha S.Entity, 0.7	
		S.rayon = pr
		PositionEntity S.Entity, px,py,pz
		ScaleEntity S.Entity, 1/MeshWidth(S.Entity)*(pr),  1/MeshHeight(S.Entity)*(pr), 1/MeshDepth(S.Entity)*(pr)			
		Return S
	End Function

	Function p_delSphereIntoSphere()
		For Local S1:TSphereInfo = EachIn TAllList
			For Local S2:TSphereInfo = EachIn TAllList			
				If S1.Entity <> S2.Entity
					Local m:Float 
					m = (S2.vPos.x - S1.vPos.x)^2+(S2.vPos.y - S1.vPos.y)^2+(S2.vPos.z - S1.vPos.z)^2
					If m > (S1.rayon + S2.rayon)^2
						FreeEntity S2.Entity
						TAllList.Remove S2
					End If
				End If
			Next
		Next
	EndFunction
EndType


Note 3DMathLib20.bmx us in the import command is
the 3D Math Library v2.0 from Chroma.

You can find the bmx file on code archive section.

here's sphere collision
http://www.blitzbasic.com/Community/posts.php?topic=63073

if that helps?

*cough* *codebox* *cough*

I think its a brilliant system on its own merits, it certainly shows what BlitzMax is capable of.

Is the next version close to a release? It's quite usable as it is but some bugs makes things a bit complicated to do sometimes.

Why not to put your Minib3d Library on http://sourceforge.net/

It's an idea

New version will be out in a few days.

good news

Ok, good news! I don't think anyone has confirmed or denied if CopyMesh() is broken in v 0.27. My copied models are suddenly turned inside out! Anyway, is that fixed in the new version or is it just me?

Yeah, to fix that you need to reverse the vertex order in one of the AddTriangle commands in AddMesh. From v2, v1, v0 to v0, v1, v2.

Simonh, In your next version of MiniB3D do you provide a linepick and collisions function like B3d ?

This has probably been solved, and I really wish I wasn't at risk of asking this a 2nd or 3rd time, but, alas...
I'll make a deal: When I learn this, I will try to round up some other information and add it to a MiniB3d FAQ at BlitzWiki.org.

I am trying to use MiniB3d with a simple but amazing LUA-utilizing thing, but to do so I need to know this:
How can I cast TMesh (or TEntity, I guess) to a Double or an Int?

@Pickle - HandleFromObject/HandleToObject. keep in mind you must Release the handle when you are done with it as it increments the reference counter.

Simonh, In your next version of MiniB3D do you provide a linepick and collisions function like B3d

All the picking functions are in, no collision functions yet though. I'll probably add some basic sphere->poly collision stuff in the release after next.

Getting a few errors in some but not all the examples in the tests folder on Mac os X
Building KBSplines
Compiling:MiniB3D.bmx
flat assembler  version 1.66
4 passes, 0.3 seconds, 701432 bytes.
Compiling:KBSplines.bmx
Compile Error: Type 'TBBType' not found
[C:/Documents and Settings/xxx/Desktop/Drop/MiniB3D-v027/MiniB3D-v027/tests/KBSplines.bmx;16;1]
Build Error: failed to compile C:/Documents and Settings/xxx/Desktop/Drop/MiniB3D-v027/MiniB3D-v027/tests/KBSplines.bmx
Process complete
Any ideas?

Thread 4