Engine Structure and Entity Loading in Blitz3D

Blitz3D Forums/Blitz3D Tutorials/Engine Structure and Entity Loading in Blitz3D

JoshK(Posted 2005) [#1]
This tutorial will show how to get the most out of your .b3d scene exported from 3D World Studio. Map geometry is only the most basic kind of information stored in a 3D World Studio scene. There's much more useful information besides just triangles and vertex positions. By accessing this data in the loaded .b3d mesh, we can add particle emitters, start positions, water, visibility culling, and just about anything else you can think of.

Files

AdvancedSceneLoadingInBlitz3D.zip

LoadWorld()

When loading a .b3d scene, we are going to replace LoadMesh() with a new command, LoadWorld(), which we will write right now. We start by loading the .b3d, and returning if the scene fails to load. We use LoadAnimMesh() instead of LoadMesh() because LoadMesh() would collapse all objects into a single mesh, which we don't want:

Function LoadWorld(file$) 
map=LoadAnimMesh(file) 
If Not map Return

Now we create a world pivot, with a number of child pivots and meshes. Each child is going to contain a certain type of object.

-The meshes entity will be parent to all map meshes found in the scene.

-The renderbrushes entity will be a collapsed mesh used for drawing all brush objects.

-The collisionbrushes entity will be a parent to all brush objects, and will be used for collision and picking. Since the renderbrushes entity is used to draw all the brush objects, the collisionbrushes entity will not be drawn. Blitz3D renders faster with single surfaces, which the renderbrushes object creates. However, separate objects are faster to run collision on, because Blitz3D performs a box test on each object. By storing the render and collision brush objects separately, our game will be most optimized for Blitz3D.

-The solidentities entity is parent to all solid entities. Solid entities are brushes or meshes that have a special classname. They can be used to create a trigger field the player steps into, an area filled with water, and lots of other things. Here, we will use a solid entity to create an invisible collision object.

-The pointentities entity is parent to all point entities in the scene. Point entities are placed in the editor, and can be lights, sound emitters, particle emitters, enemies, or just about anything else you can imagine. Here, we will use a point entity called a "playerstart" to tell our program where the camera should start out.

world=CreatePivot() 
meshes=CreatePivot(world) 
renderbrushes=CreateMesh(world) 
collisionbrushes=CreatePivot(world) 
pointentities=CreatePivot(world) 
solidentities=CreatePivot(world) 
EntityType collisionbrushes,COLLISIONTYPE_BRUSH

Now we are going to go through the scene limbs and load each limb according to what type of object it is. Each limb in the scene has properties stored in the entity name. The properties are stored as a keyname and a keyvalue, like this:

classname=light
range=800
color=255 255 255

By using the KeyValue() function, we can return a keyvalue for any entity, for whatever keyname we indicate:

keyvalue$=KeyValue$( entity, "classname" )

By selecting each entity "classname" we can determine what type of object each node in the scene is. Mesh objects will be parented to the meshes entity. Brush objects will be added to the renderbrushes entity for drawing, then parented to the collisionbrushes entity for collision:

For c=1 To CountChildren(map) 

node=GetChild(map,c) 
classname$=Lower(KeyValue(node,"classname")) 
DebugLog "Loading "+Chr(34)+classname+Chr(34)+"..." 
Select classname 
	Case "mesh" 
		EntityParent node,meshes 
		c=c-1 
		EntityType node,COLLISIONTYPE_MESH 
	Case "brush" 
		AddMesh node,renderbrushes 
		EntityType node,COLLISIONTYPE_BRUSH 
		EntityAlpha node,0 
		EntityParent node,collisionbrushes 
		c=c-1

Finally, we load our point and solid entities. We are only going to create one point and one solid entity. You will want to expand this to handle all types of entities in your engine:

	;Invisible collision brush 
	Case "field_hit" 
		EntityParent node,collisionbrushes 
		EntityType node,COLLISIONTYPE_BRUSH 
		EntityAlpha node,0 
		c=c-1 

	;Camera start position point entity 
	Case "playerstart" 
		angles$=keyvalue(node,"angles","0 0 0") 
		pitch#=piece(angles,1," ") 
		yaw#=piece(angles,2," ") 
		roll#=piece(angles,3," ") 
		If cam 
			PositionEntity cam,EntityX(node),EntityY(node),EntityZ(node) 
			RotateEntity cam,pitch,yaw,roll 
			EndIf

We finish off the function by exiting the Next loop, freeing the original loaded mesh, and returning the world pivot:

		End Select 
	Next 
FreeEntity map 
Return world 
End Function 

Seeing it in Action

Open the example.3dw scene in 3D World Studio. Select the large box covering the map meshes and open the properties editor. You will see that this brush has a classname of field_hit. It also has two parameters, CastMeshShadows and CastBrushShadows, each set to 0. This will prevent the brush from casting a shadow when lights are calculated.

http://www.leadwerks.com/developer/images/c/cc/Blitz3dentities01.jpg?

There are three point entities in the scene. Two are lights, and one is a playerstart entity. The angles property indicates the orientation of the camera:

http://www.leadwerks.com/developer/images/6/68/Blitz3dentities02.jpg?

Open the LoadWorld.bb program and run it. The camera will start at the position and orientation of the "playerstart" entity. The camera will collide with the brush walls, and with an invisible collision brush covering the meshes. Collision will not be run on the more complex mesh objects.

What Other Entities Are There?

Whatever you want! This tutorial has shown you how to place entities in the editor and load them in Blitz3D. It's up to you to decide what "kinds" of objects your engine will handle. Add a particle emitter, a monster or a block of water. Use the KeyValue() function to return any parameters you want to set in the editor. Your imagination is the only limit.


Fuller(Posted 2006) [#2]
This isn't working for me... Do you create a new entity or use a point light, because 3d world studio seems to get rid of my new keyvalues when I press apply.


Fuller(Posted 2006) [#3]
ahh.. okay now i got it. One thing that bugs me about this though, is that the world isn't pickable


RVX(Posted 2007) [#4]
Please excuse me but, I am new to this. This code however efficient is leaving me a bit confused. Can someone rewrite this code in a clearer version, using if statements etc...

Also with more comprehensive remarks statements... just so I can understand what’s going on here.

I can use this optimized version perhaps once I can understand what is going on.

***
Unless I am mistaken, this is the only way to really get what you created in 3DWS into a Blitz3d program.

(Without creating hundreds of individual objects, and corresponding textures, and then loading them manually.
Which is probably the wrong way to go about this?

****

I am not embarrassed to state, I have looked at this code for hours, and I am still struggling in various areas. Perhaps any code that leaves this much confusion, is worth re-writing clearer for the purpose of explanation, rather than efficiency, as this code is KEY and of complete importance...

I appreciate loading B3d files may seem a basic topic for some. However I think that this deserves, a bit lengthier and clearer detail, as without understanding this. All work I create in this program however wonderful is going to be useless to me.

I have looked in the 3DWS help files, and there is no more detail, than what’s here.

Unfortunately I am in a twilight world. I know Blitz3D language is not really for this forum; however 3DWS Forum is not for Blitz3D

Perhaps I am wrong but 3DWS in all its glory is (Middleware)... i.e. it's to accomplish something that can exported, and then be fed into ,and used by other Engine types...

Therefore surely a lot more time needs to be spent on this area of 3DWS.... for all engine types. If this part leaves any confusion in the users mind. Then all the enhancements in the world are not going to make much difference.

I don’t believe I am Completely stupid, I can code in 3 different assembler languages, created commercial programs, (also started computer hobbies with the 8-bit micros..where I started to code) and have been an electronics repair technician, MCSE/CNA qualified, over 10 Yrs experience in IT, but I am currently struggling to understand what's is happening here . A fair amount of this maybe to do with both B3D and 3dwS is new also.

I suspect 3DWS is a wonderful program from what I have seen,
But if I can't get through the icing, I can't comment on the cake!

Please some one help...!!

Please can someone/ or Leadwerks give an eager newbie a better, clearer, more detailed explanation of what is going on step by step. I can perhaps code it myself, if I know what's supposed to be happening. The code is short & Sweet... however for the newbie... its hell.

Also this code as seen here didn't seem to work in my app, as copied and pasted (even making sure the filename is correct) that is.

I think it also was referring to another function.... ?

Any diagramatic explanations may be useful also.


Thanks


Fuller(Posted 2007) [#5]
I suspect 3DWS is a wonderful program from what I have seen


Does this mean you dont have 3DWS? You kind of need it to understand the code because thats where you set all the keyname and stuff..


lo-tekk(Posted 2007) [#6]
@Elfology: You have to download the zip-archive stated under files in the first post.
What came to my attention is, that the exported b3d-file is useless in any other editor, since the 'real' positions of the entities are extracted from the dummy-nodes. On the other hand, it would be cool to have a real 3dws-file-loader.


RVX(Posted 2007) [#7]
Hi,

Yes I have the latest full version of 3d World Studio. However as I said, There is not a lot of useful info in the help section, or the support forum regarding this issue. The help file really only describes usage.
The forum has little clear info about this.

However I feel that for anyone to make full use of the program, and have the best experience, they need to understand this issue of export and loading in to their target engine of choice, in my case Blitz3d.

The best info I have seen so far of searching the www, and B3d & 3DWS forum, is the advanced loading technique mentioned. However it was written by I’m sure a very good programmer, however this does not mean it was written in a way to make easy understanding of what is happening, rather it was written to get the job done.

I am not rubbishing it, just for the newbie, its crucial part of everything you do in B3d and 3DWS. But I can see some shortcuts are taken, possibly for optimization, but this doesn’t help. Also what is pasted is incomplete, as references are drawn to other user –defined functions (not native blitz functions) that are in the *.Zip file, and not shown, without which the program wouldn’t work.

I am looking for some one to write bloated code, it doesn’t matter if it’s slow, so far as it’s easier to understand. That way, every newbie will get the picture, and perhaps bring to this forum, supporting ideas

Also what would be useful would be some diagrammatic detail detailing the file structure etc, so one can visualize what is happening, like in a book.

For something so important, there is surprisingly little, understandable information, addressing this topic.

I would be grateful for some help here

Thanks in advance


Mattizzle(Posted 2007) [#8]
When I first learned this code, I had already been using it. You don't have to understand a function to use a function. You only need to know how to use it.

So. Try using the LoadWorld() as is. Then, experiment.

Basically, whats going on is each type of entity in your .b3d export (from 3dws) is getting loaded into Blitz3D with different properties. Those properties should have already been defined in 3dws (try selecting an object and hitting 'Shift+Enter'. Class is the 'classname')

As for the functions that weren't explained, KeyValue() and Piece(), here is what I know: The 'playerstart' entity has an 'angles' property. In order to use the playerstart info in 3dws, 'KeyValue' returned the key values of the 'angles' property into the variable 'angles$'. It also set default values incase there weren't any already for the 'angles' property. Then, since now all three values are in a string (in the variable 'angles$'), you use peice() to seperate each value and assign them to different variables.

I hope that clears up what those two functions are for.

As for the other stuff... well I'm not sure how you can code in 3 different assembly languages but not understand a for loop and a switch statement. Look up "CountChildren()" and "GetChild()". The for loop continues until the variable 'c' equals the total children of the world pivot (an entity that is the parent of every entity in your .b3d file). The select statement (aka switch statement) just filters through the 'classnames' (a property assigned to every object in 3dws) of different types of entities you have in your .b3d file until it finds the 'classname' that the variable 'node' (which is the current entity in the loop) points to.

Well then... I might as well just write a tutorial myself...

Hope this helps to everyone struggling with this. I was one of you only a short time ago.


IPete2(Posted 2007) [#9]
Have a look inside the folder where 3DWS is, there is a read me which outlines the properties for classes which you have to set manually in 3DWS. These properties are then passed to the B3D programme as part of the info stored in the map files. You use GetChild to locate the names you set in 3DWS and then do what you like with them inside you B3D proggie.

Good luck,

IPete2.


Mattizzle(Posted 2007) [#10]
Oh helllo pete. Didn't know there was any experienced b3d people using 3dws. :-P


ss(Posted 2007) [#11]
Does not work at all. Too bad, it looked hopeful.
I have the latest versions of 3d world stuidio and Blitz3d.

Does anyone have a small tutorial program that actually works showing how to load a 3d world studio map into Blitz3d?


jfk EO-11110(Posted 2007) [#12]
I wonder why there is a user and password prompt when I click this thread. Leadwerks Deverloper thingie something wants to know a password from me when I surf the blitzbasic.com board... Fix this Josh.


Mattizzle(Posted 2007) [#13]
ss, um I beg to differ... It does work. And if you cant run the demo that's included in the .zip file of this thread, then the problem is simply the user or your computer.


RVX(Posted 2007) [#14]
IPete2

Hi, thanks for that,
could you elaborate, or post it up.
I have looked in the install directory and cannot find this info
can you post it perhaps.


Mattizzle

Thanks for your help.

I have got more attempt assistance here than from Leadwerks

Yes I can code in different languages. Yes I understand loops.
What I was asking for is a better high level explanation of the objectives of the various functions. Which you have partly answered. However I may need Pete's info

Please understand the demo detailed is set up for what looks like an fps environment. I am not really interested in this per sae.

Just the detail of the output from 3dws porting to B3d

B3D seems to use LoadMesh and AniMesh functions.

Animesh is used as the basis for 'Loadworld' because it loads the data un-collapsed. I believe really from 3DWS perspective they use it because it loads the mesh structure (Unaltered), and has a facility for the carrying other info.

However am I right in thinking, that 3DWS is depending on this to populate the structure in its bespoke way?
The loadworld function is then used to strip and reassemble the packed data, to construct a static environment and textures and faces.

This however according to the B3D manual is not the way Animesh was used. I believe you save it in a format for such as an animated mesh model, and action it to animate.

Again perhaps I am confused, hence for the asking of explanation.

In brief my understanding is3DWS is using a feature of a language B3D Animesh, in an unorthodox way to pack its created information. Hence the need for the 'Loadworld' routine to unpack this info.

The problem for me is, Blitz forum is not really the key place for this explanation. It should have come from the creators of 3dws, however they send user to blitz forum for explanations. This is why I was a bit unhappy.

If you create a piece of software that acts as a parasite. I feel it is your responsibility to detail its use for the host product, not the reverse.


In fact from my brief experience on this site. It seems a lot of games look the same, different graphics maybe?

But perhaps it’s because people are using things. Borrowing without looking at the main concepts, and why before borrowing.

In the early days, you couldn't borrow so quick without the pain of understanding stuff. That I believe is why there was a lot more creativity and variance. Now the Games market has dried up. Because people and companies are taking that approach, nick sub routines..dont understand it. Use it till you cannot get anymore out of it. Then wait for another release...

Sorry but that’s just not me.

In music most of the famous hits, did not come about when musicians seriously sat down with an intent to create a hit. It is usually happens accidentally, during a creative process. During the pain! you find other ..Perhaps better ways of doing things.

Anyway this is just an opinion, and not a flame war starter.

Thanks for your help people






Thanks again


Mattizzle(Posted 2007) [#15]
Elf, I think you may be making this LoadWorld() function more complex than it really is. If all you want to do is see what you made in 3dws in a blitz program simply:
   LoadAnimMesh("testworld.b3d")

The reason for Leadwerks' LoadWorld() function is to load each object in the exported .b3d with its own properties that can then be used for any purpose within blitz. That is all.

So again my advice is just use it, mess with it, and then try to learn it. If along that process you come across a problem that boggles you, that's when you come back here and ask about it.


RVX(Posted 2007) [#16]
Mattize,

Perhaps Im wrong but my experience is that if you do
LoadAnimMesh("testworld.b3d")

The problem I experince is you get the structures, but only one texture for the complete world surfaces.

You cannot seem to have different textures on the different surfaces. Which is really handy if you are creating an environment.

Unless something is wrong with my system.

I have tried this before. That is my understanding of why use Loadworld.

Tell me I'm wrong , then I will re-examine my install

Thanks


Mattizzle(Posted 2007) [#17]
Ok. You're wrong. But I don't think it has to do with your install. Anyways if you want some proof, replace the loadworld() function call in the file "loadworld.bb", in the .zip of this thread, with "map=LoadAnimMesh(mapfile$)" and run the program. You will still see the same textures and you should notice that you can now see the invisible "collision wall" (and that would be because it wasn't loaded into blitz with its alpha property).

Before you get mad or discouraged at this situation, let me go ahead and tell you that, once you've figured everything out, you'll find that 3dws works seamlessly with blitz3d and you will not regret your purchase.

Best regards,
Mattizzle


RVX(Posted 2007) [#18]
Thanks Mattizzle

I will have a look into this


josk(Posted 2007) [#19]
This seems to work fine for me, but im having trouble with terrains.
If I make a map with 3dws, all the meshes load etc and collision works but no terrain shows up. I'm sure this is something simple but I cant seem to get it to work. Any help appreciated.


josk(Posted 2007) [#20]
I have got the terrain showing, but I'm struggling with terrain collision.


Trader3564(Posted 2007) [#21]
The example works for me. I never tested it on any of my games cause i have none. lol.
im about to start something, i hope 3D World Studio is the way to go.
Would it be possible to place waypoints?


Mattizzle(Posted 2007) [#22]
yes