• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

crash octtree partially deciphered

Messages
86
Country
us-colorado
Worked through an octtree example and think I understand the workings of the nodes and offsets. Still have to figure out how the octants are numbered within a cube geometry (am developing a crash octtree visualization tool that I can compare to the original GMAX model shape).

Example crash octtree.


crash_riff_start label BGLCODE
db 'C','R','A','S'
dd crash_riff_end - $ - 4
BGL_CRASH_START model_crash_end, 6

Crash info header. Dunno much about this 'cept it's there.

BGL_CRASH_OCTTREE crash_end_1

Start of the crash octtree code with a label pointing to the end of the crash octtree

dw CRASH_FLAG_BUILDING_PLANE ; crash type

Guess there's more than one kind of crash you can set... maybe with water, etc... haven't really worked through this yet.

dw 23 ; nodes used

As it suggests, the number of nodes (node 0 counts as the 1st node thus 22 is the 23rd node in this example)

real4 -3.062255,0.009562,-1.492160 ; Box x,y,z
real4 8.683602,3.744388,2.984420 ; Box w,h,d

Obviously the dimensions of the crash box overall. The crash octree essentially subdivides this box by a power of 2 in each dimension for every nested level of branches. The root node itself divides the above crash box into 8 smaller boxes (2x2x2). Underlying nodes divide each box into another 8 boxes and so forth... ultimately all branches terminate at their "leaves" with either an empty or full value (254 and 255 respectively).

dw 1, 1, 1, 7, 13, 13, 13, 18 ; base offset into node table, one for each top-level branch

This line above tells you the offset to add to each node 0 term to get to the underlying branches to the remaining nodes. Empty or full octants result in offset values duplicating adjacent branches but essentially are not used for anything since the branch terminates at node 0

; So if you take branch 2 (count from 0), you add 1 to indices you encounter on that branch
; Nodes (254=empty 255=full, else an index into branch)

OCTTREE_NODE 254, 254, 0, 0, 254, 254, 0, 0 ; node 0 = root node

Node 0 is treated differently than the nodes that follow. Every example I've seen had either 0, 254, or 255 in the node 0 terms. Some have suggested that this meant node 0 refers back to itself recursively. Not true. When you add the offsets to the node 0 terms you get a correct pointer to the underlying branch nodes.

In this example, node 0 with offset taken into account could be read as:

EMPTY, EMPTY, 1, 7, EMPTY, EMPTY,13, 18

Nodes that follow get a slightly different treatment as far as the offset is concerned. The same offset applied to the node 0 term to branch to the next node is applied to all terms within the next node. Thus:


OCTTREE_NODE 254, 254, 1, 2, 3, 254, 4, 5 ; node 1
actually means:

EMPTY, EMPTY, (1+1), (2+1), (3+1), EMPTY, (4+1), (5+1) where one is the offset applied to the term followed in node 0.

or in more readable form:

EMPTY, EMPTY, 2, 3, 4, EMPTY, 5, 6

You could see where the remaining terms branch to nodes 2, 3, 4, 5, and 6 below.


OCTTREE_NODE 254, 254, 254, 254, 254, 255, 254, 255 ; node 2
OCTTREE_NODE 255, 255, 254, 255, 255, 255, 255, 255 ; node 3
OCTTREE_NODE 254, 254, 255, 255, 254, 254, 255, 255 ; node 4
OCTTREE_NODE 254, 255, 254, 254, 255, 255, 254, 254 ; node 5
OCTTREE_NODE 255, 255, 254, 255, 255, 255, 255, 255 ; node 6

This is the start of the next underlying branch. You can tell by looking at the offsets and node 0. Same rules apply as did for the branch above, though the offset you're following is now 7 instead of 1. You could also consider it as having indices to local nodes (subtracting offset from the node number to match up with the indices in the terms)

OCTTREE_NODE 254, 254, 1, 2, 254, 3, 4, 5 ; node 7 = local node 0

The above line equates to:

EMPTY, EMPTY, (1+7), (2+7), EMPTY, (3+7), (4+7), (5+7)

or in more readable form:

EMPTY, EMPTY, 8, 9, EMPTY, 10, 11, 12


OCTTREE_NODE 255, 255, 255, 254, 255, 255, 255, 255 ; node 8 = local node 1
OCTTREE_NODE 254, 254, 254, 254, 255, 254, 255, 254 ; node 9 = local node 2
OCTTREE_NODE 254, 254, 255, 255, 254, 254, 255, 255 ; node 10 = local node 3
OCTTREE_NODE 255, 255, 255, 254, 255, 255, 255, 255 ; node 11 = local node 4
OCTTREE_NODE 255, 254, 254, 254, 255, 255, 254, 254 ; node 12 = local node 5

This is the start of the next underlying branch. You can tell by looking at the offsets and node 0. Same rules apply as did for the branch above, though the offset you're following is now 13 instead of 7.

OCTTREE_NODE 1, 2, 3, 4, 254, 254, 254, 254 ; node 13 = local node 0

Equates to:

(1+13), (2+13), (3+13), (4+13), EMPTY, EMPTY, EMPTY, EMPTY

or in more readable form:

14, 15, 16, 17, EMPTY, EMPTY, EMPTY, EMPTY


OCTTREE_NODE 254, 254, 255, 255, 254, 254, 254, 254 ; node 14 = local node 1
OCTTREE_NODE 254, 254, 255, 254, 255, 255, 255, 255 ; node 15 = local node 2
OCTTREE_NODE 255, 255, 254, 255, 254, 254, 254, 254 ; node 16 = local node 3
OCTTREE_NODE 255, 255, 255, 255, 254, 254, 254, 254 ; node 17 = local node 4

Etc... except base offset is now 18

OCTTREE_NODE 1, 2, 3, 4, 254, 254, 254, 254 ; node 18 = local node 0
OCTTREE_NODE 254, 254, 254, 255, 255, 255, 255, 255 ; node 19 = local node 1
OCTTREE_NODE 254, 254, 255, 255, 254, 254, 254, 254 ; node 20 = local node 2
OCTTREE_NODE 255, 255, 255, 255, 254, 254, 254, 254 ; node 21 = local node 3
OCTTREE_NODE 255, 255, 255, 254, 254, 254, 254, 254 ; node 22 = local node 4

That's it for the node info.

crash_end_1 label word

Label indicating the end of the crash octtree

model_crash_end label word
BGL_RETURN
crash_riff_end label BGLCODE

By the way, this wasn't a particularly useful crash tree as it was generated with lots of empties in it and didn't cause crashes like it should have for the desired object (originally made outside of GMAX). Still, the tracing through the tree has held up in other examples I've looked at that work.

Hope this info helps... at least it's beginning to make sense to me. Just have to figure out which octant goes with which of the 4 sub-boxes in a cube.

Prof K.
 
Thanks, very nice description (I think I will have to read it again to fully understand it all :)).

Here are the different types of crashes you can have:

Code:
CRASH_FLAG_NONE			equ	00	; NOTE:  THESE ENUMS ARE ALSO DEFINED
CRASH_FLAG_MOUNTAIN		equ	02	;	 IN INCLUDE\FS6DEF.H AND MUST
CRASH_FLAG_GENERAL		equ	04	;	 BE CHANGED IN BOTH PLACES
CRASH_FLAG_BUILDING_EYE		equ	06	; based on eye position
CRASH_FLAG_SPLASH		equ	08
CRASH_FLAG_GEAR_UP		equ	10
CRASH_FLAG_OVERSTRESS		equ	12
CRASH_FLAG_BUILDING_PLANE	equ	14	; based on plane position
CRASH_FLAG_AIRCRAFT		equ	16
CRASH_FLAG_FUEL_TRUCK		equ	18
CRASH_FLAG_OBJECT		equ	20
 
Thanks Arno, that's useful information! Reading my own post above now makes me think I should come up with a diagram or pseudo-code instead of trying to explain with sentences alone. Even I had difficulty walking through it. :)

Basic idea is that each term in the base offset list gets added to the respective term in node 0 to point to the next branch. Once you follow a branch to another node, then the offset used to get to that branch is applied to all terms within the new node. This is true for each nested level of nodes.

I'm still working on a crash octtree visualization tool to see what each octant's position within their respective cube happens to be.

Prof K.
 
Last edited:
some additional info:

order of octant coverage (relative to divided cube or subcube southwest bottom corner)

for unrotated objects, +x is east, +y is north, +z is up

branch (x,y,z)
----------------
octant 0 (0,0,0)
octant 1 (0,1,0)
octant 2 (0,0,1)
octant 3 (0,1,1)
octant 4 (1,0,0)
octant 5 (1,1,0)
octant 6 (1,0,1)
octant 7 (1,1,1)
 
Last edited:
An image to help visualize the octree structure.

09042005015tg.jpg
 
Last edited:
I made small program, which analyzes ASM and is able to display crashboxes in FS and gmax/3dsmax. You can also define your own crashboxes in gmax/3dsmax, edit your ASM file with them, compile and have exact building crashes in FS.
But documentation is still not in English, i'll make it and post link here soon.
 
Thanks, would certainly be interesting to look at.

Now that I am coding on the MDL Tweaker again, I am also looking at ways to show/edit the crash box there. In MDL Tweaker I read the binary MDL file directly, so there are no ASM files to play with.
 
arno said:
Thanks, would certainly be interesting to look at.

Now that I am coding on the MDL Tweaker again, I am also looking at ways to show/edit the crash box there. In MDL Tweaker I read the binary MDL file directly, so there are no ASM files to play with.

It's quite simple do show it FS or gmax. Yes, it's better to read directly MDL ... I'll make it in next version of program. You can have a look, http://mzak.webzdarma.cz/fs/fsbox/ , but still not in English :-)
 
Thanks, looks interesting from the images (my czech is not good enough to read the text :D).

At the moment I have not yet coded the preview picture of the MDL, so I have nothing to show the crashbox info in. But it would indeed be an interesting option to show to users.
 
Hi anatolij.

Very interesting stuff about the crashboxes at your website.

BGLC_9 is avalable here... in the 'sticky' at the top of this forum. It is an enhanced version of BGLC, that will compile FS9 scenery objects. It's not available from Microsoft.

Dick
 
Back
Top