Nif Format/Mopp
From NifTools
What is a mopp
A mopp appears to be a script used by the engine to speed up collision detection of arbitrary (not necessarily convex) shapes. In Oblivion they are stored in the "Mopp Data" field of bhkMoppBvTreeShape blocks. As far as we understand, the script can quickly decide which triangles are in the neightborhood of a given point in space.
What is certain about mopps:
- a mopp is a binary decision tree
- the final nodes of this decision tree are triangles, and they make up all triangles of the mesh
Some theories of what mopps do:
- a mopp divides up space into regions that have a particular triangle
- a mopp first divides the non-convex mesh into groups of triangles that are convex, and then hulls each part into a K-DOP (K discrete oriented polytope)
- a mopp a bounding volume tree made up of AABB nodes, K-DOP nodes, & leaf nodes. The binary bounding volume tree is hierarchical and each binary split reduces the bounding volume of the triangle primitives. leaf node confines only one triangle primitive.
Note that in each mopp the space is discretized on a 256x256x256 grid.
Mopp syntax
Each command in a mopp consists of an opcode (a byte), followed by zero or more arguments (each of which is also a byte). These are all opcodes used in Oblivion mopps, along with their function:
0x01 a b c: unknown test0x02 a b c: unknown test0x03 a b c: unknown test0x04 a b c: unknown test
0x05 a: jumpabytes0x06 a b: jumpa*256 + bbytes
0x09 a: increment triangle offset bya0x0A a b: increment triangle offset bya*256 + b0x0B a b c d: set triangle offset toc*256 + d;aseems always 1, andbseems always 0
0x10 a b c: if x>a then execute blockcbytes further; if x<=a and x>=b then execute next block and blockcbytes further; if x<b then only execute next block0x11 a b c: like0x10but for y0x12 a b c: like0x10but for z0x13 a b c: like0x10but for y + z0x14 a b c: like0x10but for y - z0x15 a b c: like0x10but for x + z0x16 a b c: like0x10but for x - z0x17 a b c: like0x10but for x + y0x18 a b c: like0x10but for x - y0x19 a b c: like0x10but for x + y + z0x1A a b c: like0x10but for x + y - z0x1B a b c: like0x10but for x - y + z0x1C a b c: like0x10but for x - y - z
0x20 a b: execute next block and/or block atbbytes further depending on result of an unknown test involvinga0x21 a b: like0x200x22 a b: like0x20
0x23 a b c d e f: execute blockc*256 + dbytes further and/or blocke*256 + fbytes further depending on result of an unknown test involvingaandb0x24 a b c d e f: like0x230x25 a b c d e f: like0x23
0x26 a b: exit ifx<aorx>b0x27 a b: exit ify<aory>b0x28 a b: exit ifz<aorz>b
0x30...0x4F: select triangle0+offset...31+offsetand exit0x50 a: select trianglea+offsetand exit0x51 a b: select trianglea*256+b+offsetand exit0x53 a b c d: select trianglec*256+d+offsetand exit
