## Reverse Engineering Lugaru assets

- rudel_ic
- official Wolfire heckler
**Posts:**2193**Joined:**Sun Aug 28, 2005 11:19 pm**Location:**Hamburg City-
**Contact:**

Turns out these bytes are not the same throughout all models. It is still unclear what they're up to.

But the number of bytes these control bytestrings or whatever the hell they are contain is the same.

The first test will simply write nonsense into these bytes, should be interesting to see how Lugaru.exe handles that.

The scary part is that now that I've seen the pattern, I can't unsee it. It jumps at me when I look at the HEX. nnnNNNOOOOOOOOOO

But the number of bytes these control bytestrings or whatever the hell they are contain is the same.

The first test will simply write nonsense into these bytes, should be interesting to see how Lugaru.exe handles that.

The scary part is that now that I've seen the pattern, I can't unsee it. It jumps at me when I look at the HEX. nnnNNNOOOOOOOOOO

- rudel_ic
- official Wolfire heckler
**Posts:**2193**Joined:**Sun Aug 28, 2005 11:19 pm**Location:**Hamburg City-
**Contact:**

So let's concentrate what's there apart from these padding bytes.

As mentioned in the zip quote, we have

3*12 triangle mapping indices, type unknown, originally assumed to be integer;

3*12 texture mapping x offsets, most likely floats and

3*12 texture mapping y offsets, most likely floats.

floats use 4 bytes, so assuming the uv mapping is at the end of the file, the triangle mapping indices must end at the address filesize-3*12*2*4=filesize-288 bytes, ignoring the padding.

That doesn't add up; apart from the padding, there are only 144 bytes left (see pattern demo image on previous page).

Let's approach it from above; assuming the indices are actually shorts instead of integers, they take up 3*12*2=72 bytes, so that would be where the uv mapping begins, again ignoring the padding.

That leaves us with 72 bytes for uv mapping.

72/2 (1 mapping per axis) is 36, 36/3 (for each vertex of a triangle) is 12, 12/12 (for each triangle) is 1.

A float of 1 byte width hasn't been invented yet.

So it doesn't add up.

As mentioned in the zip quote, we have

3*12 triangle mapping indices, type unknown, originally assumed to be integer;

3*12 texture mapping x offsets, most likely floats and

3*12 texture mapping y offsets, most likely floats.

floats use 4 bytes, so assuming the uv mapping is at the end of the file, the triangle mapping indices must end at the address filesize-3*12*2*4=filesize-288 bytes, ignoring the padding.

That doesn't add up; apart from the padding, there are only 144 bytes left (see pattern demo image on previous page).

Let's approach it from above; assuming the indices are actually shorts instead of integers, they take up 3*12*2=72 bytes, so that would be where the uv mapping begins, again ignoring the padding.

That leaves us with 72 bytes for uv mapping.

72/2 (1 mapping per axis) is 36, 36/3 (for each vertex of a triangle) is 12, 12/12 (for each triangle) is 1.

A float of 1 byte width hasn't been invented yet.

So it doesn't add up.

- Chainsaw man
**Posts:**1492**Joined:**Mon Mar 17, 2008 6:13 am**Location:**New Zealand

- Chainsaw man
**Posts:**1492**Joined:**Mon Mar 17, 2008 6:13 am**Location:**New Zealand

Vertices are still something to work from. Knowing what you've got is the first step to finding out what you're missing. Or I could just be blowing crap out my arse. You decide.rudel_ic wrote:No, because all I've got is the vertices.

Just something a little random - maybe David is really bad at modelling, and those really large numbers are like the lengths or angles of the hypotenuses.

Or maybe you're appraching the problem the wrong way and the values are actually below zero.

- rudel_ic
- official Wolfire heckler
**Posts:**2193**Joined:**Sun Aug 28, 2005 11:19 pm**Location:**Hamburg City-
**Contact:**

To get to a working 3D model format, you always do it like this:

1. You set up the vertices

2. You say which vertices form triangles

3. You do texture mapping per triangle

1 consists of 3D values from continuous space, 2 of indices from discrete space, 3 of 2D values from continuous space.

Values for texture mapping are usually between 0 and 1.

That's how it works.

No matter how naiive David was when he wrote Lugaru (and judging by the end product, he was very aware of how things work traditionally in game engines), this way of operating is so common that he would have heard of it.

The latest he would have come across it would have been when he actually rebuilt the models with OpenGL instructions, because that's basically how it's done at that stage.

About indices below zero: That is only possible for relative indices:

next index = current index + offset

That's required in very few cases. It is usually frowned upon because relative indices potentially lead to debug hell and have practically no benefits.

There's really no point to them if you have thousands of vertices you access by index. It just adds useless instructions.

So considering all that, I think the assumed basic layout (1.,2.,3.) applies.

If it doesn't work like that, I'm not going to put one more second of effort into it anyway because then, it could be anything. So we'll just have to make sense of it.

1. You set up the vertices

2. You say which vertices form triangles

3. You do texture mapping per triangle

1 consists of 3D values from continuous space, 2 of indices from discrete space, 3 of 2D values from continuous space.

Values for texture mapping are usually between 0 and 1.

That's how it works.

No matter how naiive David was when he wrote Lugaru (and judging by the end product, he was very aware of how things work traditionally in game engines), this way of operating is so common that he would have heard of it.

The latest he would have come across it would have been when he actually rebuilt the models with OpenGL instructions, because that's basically how it's done at that stage.

About indices below zero: That is only possible for relative indices:

next index = current index + offset

That's required in very few cases. It is usually frowned upon because relative indices potentially lead to debug hell and have practically no benefits.

There's really no point to them if you have thousands of vertices you access by index. It just adds useless instructions.

So considering all that, I think the assumed basic layout (1.,2.,3.) applies.

If it doesn't work like that, I'm not going to put one more second of effort into it anyway because then, it could be anything. So we'll just have to make sense of it.

Anyway, to try and help a bit, let's run through what you've got logically.

1. 8 sets of bytes that make up co-ordinates for 8 vertices. There are 96 bytes (24 sets of 4) in the original vertex co-ordinates section in the hex. Therefore each vertex takes up 12 bytes. If computers work logically.

2. 12 sets of 24 bytes (6 bytestrings of 4 byte length), which you currently cannot identify. You therefore have 288 unknown bytes out of 532.

Now, I can see a problem already. 9 shouldn't have a duplicate. I can only see one instance of 3F 7F FF FE 3F 7F FF FE. If you take another look at the hex, you'll see I'm right. Number 10 appears to be the problem, it should be:

Code: Select all

`33 00 00 00 3F 80 00 00 3F 80 00 00 3F 80 00 00 3F 80 00 00 00 00 00 00 `

- rudel_ic
- official Wolfire heckler
**Posts:**2193**Joined:**Sun Aug 28, 2005 11:19 pm**Location:**Hamburg City-
**Contact:**

12 different texture mappings, each with an x and y float for each corner of a triangle:

3 (corners of triangle)

* 2 (x and y)

* 4 (bytes)

* 12 (triangles)

So what you're saying is that the texture mapping doesn't follow the triangle indexing, but it's inbetween it, eh?

Well, then maybe it is like this: After each triangle indexing follows its texture mapping.

Holy shit, that makes some sense.

3 (corners of triangle)

* 2 (x and y)

* 4 (bytes)

* 12 (triangles)

So what you're saying is that the texture mapping doesn't follow the triangle indexing, but it's inbetween it, eh?

Well, then maybe it is like this: After each triangle indexing follows its texture mapping.

Holy shit, that makes some sense.

- rudel_ic
- official Wolfire heckler
**Posts:**2193**Joined:**Sun Aug 28, 2005 11:19 pm**Location:**Hamburg City-
**Contact:**

It isn't 3x int, it's 6x short; I checked it by parsing shorts and looking at them, they are never greater than the number of vertices. The rest seems to be correct, they seem to be floats.

I don't understand why it's 6x short though.

And the floats have weird values, although that could be an issue that's introduced by my parser. I simply assumed IEEE 754 floating point "single format" bit layout.

Behold some output:
Note that the assumption " 3xu, then 3xv floats " has been taken into account here.

I don't understand why it's 6x short though.

And the floats have weird values, although that could be an issue that's introduced by my parser. I simply assumed IEEE 754 floating point "single format" bit layout.

Behold some output:

Code: Select all

```
TexRep of Solid assets/Box.solid:
Number of vertices: 8
Number of triangles: 12
Coords for vertex 0:
x: -25.0
y: 23.000006
z: -22.999994
Coords for vertex 1:
x: -25.0
y: -26.000006
z: 25.999992
Coords for vertex 2:
x: -25.0
y: -25.999992
z: -23.000006
Coords for vertex 3:
x: -25.0
y: 22.999992
z: 26.000006
Coords for vertex 4:
x: 25.0
y: 23.000006
z: -22.999994
Coords for vertex 5:
x: 25.0
y: -25.999992
z: -23.000006
Coords for vertex 6:
x: 25.0
y: -26.000006
z: 25.999992
Coords for vertex 7:
x: 25.0
y: 22.999992
z: 26.000006
Vertex indices for triangle 0: 2 1 1
Vertex indices for triangle 1: 0 1 1
Vertex indices for triangle 2: 4 0 0
Vertex indices for triangle 3: 0 5 5
Vertex indices for triangle 4: 2 6 6
Vertex indices for triangle 5: 1 7 7
Vertex indices for triangle 6: 4 3 3
Vertex indices for triangle 7: 5 0 0
Vertex indices for triangle 8: 2 5 5
Vertex indices for triangle 9: 1 6 6
Vertex indices for triangle 10: 7 6 6
Vertex indices for triangle 11: 4 6 6
Leftover shorts for triangle 0: 0 0 0
Leftover shorts for triangle 1: 3 3 0
Leftover shorts for triangle 2: 3 3 0
Leftover shorts for triangle 3: 2 2 0
Leftover shorts for triangle 4: 1 1 0
Leftover shorts for triangle 5: 3 3 0
Leftover shorts for triangle 6: 7 7 0
Leftover shorts for triangle 7: 4 4 0
Leftover shorts for triangle 8: 6 6 0
Leftover shorts for triangle 9: 7 7 0
Leftover shorts for triangle 10: 4 4 0
Leftover shorts for triangle 11: 5 5 0
UV mapping for triangle 0:
u 2.4787812E19 v 2.4787812E19
u 2.9802322E-8 v 2.4787812E19
u 2.4787812E19 v 0.0
UV mapping for triangle 1:
u 2.4787812E19 v 0.0
u 2.9802322E-8 v 2.4787812E19
u 2.9802322E-8 v 0.0
UV mapping for triangle 2:
u 2.4787812E19 v 2.4787812E19
u 2.4787812E19 v 1.47746875E12
u 0.0 v 1.47746875E12
UV mapping for triangle 3:
u 0.0 v 0.0
u 2.4787812E19 v 2.4787812E19
u 0.0 v 2.4787812E19
UV mapping for triangle 4:
u 2.4787812E19 v 0.0
u 2.9802322E-8 v 0.9999999
u 2.9802322E-8 v 0.0
UV mapping for triangle 5:
u 2.9802322E-8 v 2.4787812E19
u 2.4787812E19 v 0.0
u 2.9802322E-8 v 0.0
UV mapping for triangle 6:
u 2.4787812E19 v 2.4787812E19
u 0.0 v 1.47746875E12
u 0.0 v 2.4787812E19
UV mapping for triangle 7:
u 2.4787812E19 v 2.4787812E19
u 0.0 v 0.0
u 2.4787812E19 v 0.0
UV mapping for triangle 8:
u 2.4787812E19 v 0.0
u 2.4787812E19 v 0.9999999
u 2.9802322E-8 v 0.9999999
UV mapping for triangle 9:
u 2.9802322E-8 v 2.4787812E19
u 2.4787812E19 v 2.4787812E19
u 2.4787812E19 v 0.0
UV mapping for triangle 10:
u 0.0 v 0.0
u 0.0 v 2.4787812E19
u 2.4787812E19 v 0.0
UV mapping for triangle 11:
u 2.4787812E19 v 0.0
u 0.0 v 2.4787812E19
u 2.4787812E19 v 2.4787812E19
```