As any of you who are likely to read this would know, I've recently completed code for importing a trianglesoup from an OBJ file, optimizing it, generating a BSPTree from it, and saving it to a custom file format.

I am looking for expressions of interest in a collaborative and open-sourced BSP-based game engine project. You don't need to be familiar with OpenGL, ATC or OOP models, but it would be helpful.

The only requirements are an interest in MASM coding and 3D games and a willingness to learn and to try new things.

The project will be comprised of three interrelated components:
-Game Engine Core
-Game Server
-Game Client

I'd like to see the Core capable of operating in Game or Developer modes, so that N users could join a "game", and edit the same world at the same time. I might be planning too far in advance, but if this is an underlying design paradigm then a lot of rework can be avoided later.

Please correspond via this thread unless otherwise advised.
Posted on 2005-03-17 01:52:25 by Homer
sounds interesting, I don't know alot about BSP but have willingness to learn and try new things as you put it.

Here is what I did, close to a year ago.? It includes a .OBJ mesh and can read up to 4-sided polys. left mouse button rotates, right button zooms.
Posted on 2005-03-20 10:54:54 by drarem
I dont know much about BSP, I want to code something 3d in masm
I could contribute with SSE, generating/rotating/transform on the fly two circles parallel,animation rotates around several axis+ sizechange, esc quits, best viewed at 8bit color

Posted on 2005-03-20 13:49:39 by daydreamer
I see OBJ as an intermediate file format.
Easy to read, easy to modify, terribly inefficient.

My OBJ loader code reindexes all 2D and 3D indices to unique instances of those values.
That is to say, it eliminates duplicates of Vec2 and Vec3 values and repairs indices.
At that point I am ready to process the polygons in some way.
BSP is what I'm using at the moment, implementing the tree generator wasn't too hard.

A BSP Tree node is basically a struct that contains three things:
Some kind of ID tag identifying a Polygon from which a Dividing Plane was obtained, and two pointers to Child nodes which will contain all the Polygons which exist on either side of the aforementioned Divider plane.

BSPNode struct
SplitterPolyID dd ?
pFront dd ?
pBack dd ?
BSPNode ends

When I say Polygon, it means Triangle.
If we can afford to make the assumption that more complex polygons are always FLAT (planar),
then this stuff will work for any polygon, but generally speaking, this stuff is for Triangles.

Generating a Tree from a Polygon List involves choosing from that list one Polygon to use as a Dividing Plane, then classifying all the other Polys against that Plane, and sorting them into two Child Lists, and handing each to a Child Node for recursive processing.
Polygons which are cut by the dividingplane must be split into several new polygons, and the original polygon should be discarded.

Once the Tree has been generated, it's very easy to render a correct scene given any position for the camera.
Starting at the root node, you check if the camera is in front of or behind the node's dividingplane, and then "walk the other side child, then the same side child", then render the dividingplane's poly.
Read that three times and it will become as clear as mud :)

I've put a recent version of the code at
Let me know what's missing and I'll remedy it.
Take a look at this code and see if you can stomach it.
The manager class VertexManager needs to be renamed as Vec3Manager.
All management classes need overhauling, Ultrano has recently provided me with source to smAlloc MM so that I might create a more streamlined fixed-size-element array manager.
Posted on 2005-03-24 21:00:54 by Homer
after message 18 polygons gonna be processed
message:MeshLoader Instance @3C3F10
after that it crashes and windows comes ups with message

do you mind if I test it with something more funnier than a hipolycountcube?
Posted on 2005-03-28 12:28:50 by daydreamer
No, test it with whatever you liked.
My final version of the old bspgenerator was fed the following geometry successfully:
I created 24 triangles in Maya, and rotated each of them randomly , and with a small random translation each, resulting in an intersecting mangled mess.
I then exported that to OBJ and fed the OBJ to the old BSPgen.
Successfully processed this complex beastie.
The old OBJ importer was bad at importing large models.

Currently rewriting BSP code to support new HSM file format.
HSM is a class for importing OBJ and a file format for exporting.
Maya6.0 compatible.
Better materials handling.
Handles larger models (tested with a 7000 poly model recently, haven't really pushed it at all)
Should not be bugs in loader code at all.

If you want to get in now on this revision, I'll put up the existing codebase.
I'm rewriting the BSPgen to handle triangles AND quads at once intelligently.
IE a triangle can be split into a triangle and a quad, rather than three triangles.
HSM already handles both polygons and keeps them grouped by material, meaning it's easy to render just the faces of a particular material in an object comprised of >1 material, or to render the object's faces in order of materials, eliminating texture thrashing.

Posted on 2005-05-02 03:14:32 by Homer
Hi Home2k, I'm returned again too look whats going on. Probaly you forgot me. I was some where other place doing some thing unknown stuff%). I see you try to Render BSP, should I post ProbinkGL again? A new version: Collision works now with gravity and jumping!! But theres some problem with calculating FPS probaly, so it is possible to go throught wall or floor. Are you interest?
Posted on 2005-05-08 17:24:33 by valka
Sure post it again, though I doubt I can use much of it.
I'm not loading a BSP someone else made.
I'm loading a BSP I generated with my own generator, so things are a bit nonstandard, as you can see above.
Still, I'm sure I can use the lightmap stuff.

I'm pretty sure I understand why you are crashing through surfaces.
My collision detections are not dependant on time.
My algorithm does not require the intersection time to produce accurate collisions and responses.
I have posted code in regard to sphere/plane collisions.
These are parts A and B of a two-stage test.
We actually test a theoretical line from the old to the new sphere origins against the plane of the triangle, and then if we find a collision, we test the resulting intersectionpoint on the plane against the triangle geometry to make sure it's inside the triangle.

Does this sound anything like your existing collision detection framework?
Posted on 2005-05-09 10:31:48 by Homer
Cool! An own generated BSP. Here's the source of latest ProbnikGL:
You will find that I use OOP much, but I can't call them OOP modules because they still depend on other modules or main .asm file. What else? Collision detection is not good in ProbnikGL, I can't find mistake or something that I could change to make it better. Source is big and I don't remember well how it actually works%)
Posted on 2005-05-10 09:17:53 by valka
Im interested. What should I do? I hope I can get to this site everyday. I always everyday at masmforum use name Farabi. I dont know about C programming. I upload my own project here. Please check at GL init function on on my code to see the Open GL code.
Posted on 2005-05-11 22:13:57 by realvampire
You should begin by bringing yourself up to speed.
Check out all the stuff I've posted regarding BSP and collision detections.
You need to understand what a surface normal is.
You need to understand what an infinite plane is.
Infinity is not something we calculate :)
You need to understand how to test what side of a plane any 3D point lays.
Is the point in front of the plane, behind the plane, or resting on the plane?
Once you understand these few things, try writing some demo code to test a point and a plane.
It doesn't need any window at all, we can use messagebox or something.. I mean really simple.
That stuff covers about 40 percent of our math requirements in this project.
Having all this under your belt, yell out again and I'll lay some more homework on you :)
Also, feel free to whine in public if you find yourself stumped.
This stuff can look scary at first, but really, we'll write a few procs and then it'll be a matter of calling procs as usual, nothing scary about it :)
Posted on 2005-05-12 22:00:59 by Homer
Hi. DO you have a 3D rotation code? I have never completed it.
Posted on 2005-05-13 22:36:45 by realvampire

I have all kinds of 3D rotation code :)
You have to be very specific about this stuff.
What do you want to rotate? How do you want to rotate it?

By what, I mean, are we rotating a 3D object with many vertices in it?
Are we rotating just a 3D line around a 3D point? Etc.

By how, I mean, are we rotating around a particular axis, like X, Y and Z?
Or are we rotating about an arbitrary axis, ie a 3D line as our axis of rotation?

Then we have to consider other things like - does the target of our rotation have a 3D offset to its rotation origin (ie, is it built off-center), and is this rotation part of a hierarchy ie a human limb chain?

Rotation can be very simple, or very hard, depending on what you want to do.
The first way I learned to rotate was using trigonometry (sine and cosine), and I was only able to perform this in 2D. Later I learned how to perform it in 3D using trigonometry.
Now I can perform it using matrix math as well.

glRotatef is an OpenGL function which takes four params, and is probably the simplest way to rotate stuff.
The first param is a floating point Angle in degrees.
The other three define a vector which forms the rotation axis.
For example, to rotate about the Y axis, we set the rotation axis to 0.0f,1.0f,0.0f
We call it just before constructing our objects within our Render procedure.

The function calculates and then combines the rotation matrix with the current world matrix and applies the result as the new world matrix.
This means after we call it, everything we draw gets rotated - we have in fact rotated the world by the opposite 3D rotation, and are drawing things straight :)
By surrounding such calls with calls to glPushMatrix and glPopMatrix, we can perform rotations which are not cumulative.
By nesting this behaviour in code we can perform relative rotation and hierarchical rotation.
Once we understand all this stuff we should learn how to use matrices ourselves and provide our own matrix math procs or macros, and learn to apply the rotation matrices we create (by multiplying them with the world matrix) and also we should learn how to "slap a translation into a 4x4 rotation matrix" to quickly create combined translation/rotation matrices.
One step at a time :)
Posted on 2005-05-14 01:21:10 by Homer
Homer - Tell me, have you looked in ProbnikGL source? IT SUCKS??? TELL ME THAT IT SUCKS, I KNOW IT :D
Posted on 2005-05-16 13:18:16 by valka
I haven't reviewed his repost yet, since as many of you are aware, my daily driver recently  spontaneously combusted, demoting me to a lowly 333.
I do however have a clear recollection of the source from when he was developing it, at the time he was adding lightmap support.
To be honest, at first glace it appears awful, then after a while, you'll realize it's actually quite efficient code, it's an objectless and naiive approach he's taken. That's not a bad thing imho :)
I don't recall anything particularly obtuse about his source, but perhaps he's rewritten it for the worse since then.. I'm not in a position to test it, so I haven't bothered looking.
My biggest priority at the moment is a new motherboard :(
Posted on 2005-05-17 02:38:12 by Homer
Hai. After this is finish. I have understand anything I need.

RotatingXYZ proc x:dword,y:dword,z:dword,xAng:dword,yAng:dword,zAng:dword
LOCAL xt,yt,zt:dword
LOCAL xt2,yt2,zt2:dword
LOCAL xt3,yt3,zt3:dword

;        Rotate around x-axis                                                  ;
;        YT = Y * COS(xang) - Z * SIN(xang) / 256                              ;
;        ZT = Y * SIN(xang) + Z * COS(xang) / 256                              ;
;        Y = YT                                                                ;
;        Z = ZT                                                                ;
;                                                                              ;

invoke UMGetPosRound,y,xAng
mov yt,edx
invoke UMGetPosRound,z,xAng
sub eax,yt
mov yt,eax

invoke UMGetPosRound,y,xAng
mov zt,eax
invoke UMGetPosRound,z,xAng
add edx,zt
mov zt,edx

;        Rotate around y-axis                                                  ;
;        XT = X * COS(yang) - Z * SIN(yang) / 256                              ;
;        ZT = X * SIN(yang) + Z * COS(yang) / 256                              ;
;        X = XT                                                                ;
;        Z = ZT                                                                ;
;                                                                              ;

invoke UMGetPosRound,x,yAng
mov xt2,edx
invoke UMGetPosRound,z,yAng
sub eax,xt
mov xt2,eax

invoke UMGetPosRound,x,yAng
mov zt2,eax
invoke UMGetPosRound,z,yAng
add edx,zt2
mov zt2,edx

;        Rotate around z-axis                                                  ;
;        XT = X * COS(zang) - Y * SIN(zang) / 256                              ;
;        YT = X * SIN(zang) + Y * COS(zang) / 256                              ;
;        X = XT                                                                ;
;        Y = YT                                                                ;

invoke UMGetPosRound,x,zAng
mov xt3,edx
invoke UMGetPosRound,y,zAng
sub eax,xt3
mov xt3,eax

invoke UMGetPosRound,x,zAng
mov yt3,eax
invoke UMGetPosRound,y,zAng
add edx,yt3
mov yt3,edx

mov edx,xt3
; add edx,xt2

mov eax,yt3
; add eax,yt

xor ecx,ecx
add ecx,500

RotatingXYZ endp

I confused about the result, what should I do with all the value, just add it all?
Posted on 2005-05-22 02:02:47 by realvampire
This is what we call a compound rotation.
The algorithm you are using creates a lot of error, due to rotation about one axis rotating another axis.

Your algorithm has three parts.
You are really performing three separate rotations.
You are rotating about X, which modifies Y and Z.
You are rotating about Y, which modifies X and Z.
You are rotating about Z, which modifies X and Y.

You don't add anything.
You have input X,Y,Z values, some math operations, then X,Y,Z output values.

Try simplifying the algo to only rotate about a single axis at a time to understand it better.
Posted on 2005-05-22 22:34:58 by Homer
This is a single rotation.

invoke UMGetPosRound,x,zAng
mov xt3,edx
invoke UMGetPosRound,y,zAng
sub eax,xt3
mov xt3,eax

invoke UMGetPosRound,x,zAng
mov yt3,eax
invoke UMGetPosRound,y,zAng
add edx,yt3
mov yt3,edx

And what should I do next?
Posted on 2005-05-23 06:40:45 by realvampire
The reason you are confused is because you are looking at a code snippet which you don't understand, and totally ignoring the comments which are giving you 2D trig formula for rotation of a point about a given axis.

Rotation around the X axis :
;        YT = Y * COS(xang) - Z * SIN(xang) / 256
;        ZT = Y * SIN(xang) + Z * COS(xang) / 256

Let's make this more clear.
Where Theta is an angle of rotation (amount to rotate)
New Y = ( Old Y * ( COS THETA)) - ( Old Z * ( SIN THETA ))
New Z = ( Old Y * ( SIN THETA )) + ( Old Z * ( COS THETA ))

Ignoring the /256 because its a stupid scalar and is not part of the formula.

Now, here's the part where you kick yourself.
Your 3D point (X, Y, Z) when rotated about the X axis WILL NOT ALTER X VALUE.
Rotation around X affects Y and Z only.
So - in the above example, take ANY 3D point in space (XYZ), plug the values into the above formula, and out comes the new XYZ (in our case, X doesnt change)
Posted on 2005-05-24 08:05:32 by Homer
For the record, even though this formula and its 3D variant work, they are imperfect.
For rotating about a single axis, we're really doing a 2D rotation, and thats fine, trig will work ok.
But as soon as you want to apply a compound rotation, you'll have problems with that method.
Still, it's the same place I started learning this stuff, and I'd say it's still worth learning this method.
Posted on 2005-05-24 08:09:02 by Homer