rswiki-book/OB3.mediawiki

111 lines
2.9 KiB
Plaintext
Raw Normal View History

2012-11-23 14:26:03 -05:00
[[Category RSC]]
Work in progress.
2012-11-25 17:19:57 -05:00
This page refers to .ob3, a custom format for 3D models created by Jagex. It is used by the RuneScape Classic engine since client version #74. For the earlier version of the format see [[OB2|OB2]].
2012-11-23 14:26:03 -05:00
2012-11-26 16:37:35 -05:00
<pre>public class OB3Model {
2012-11-25 13:43:36 -05:00
private static final int num_seq = 0xbc614e;
public int gouraud_shade[];
public int vert_count;
public int vert_x[];
public int vert_y[];
2012-11-25 16:09:23 -05:00
public int vert_z[];
2012-11-25 13:43:36 -05:00
public int face_count;
public int face_v_count[];
2012-11-26 16:37:35 -05:00
public int faces[][];
2012-11-25 13:43:36 -05:00
public int face_back[];
public int face_front[];
public OB3Model(byte data[], int offset) {
2012-11-26 16:37:35 -05:00
int vert_count = get_u_short(data, offset);
2012-11-25 13:43:36 -05:00
offset += 2;
2012-11-26 16:37:35 -05:00
int face_count = get_u_short(data, offset);
2012-11-25 13:43:36 -05:00
offset += 2;
2012-11-26 10:36:07 -05:00
vert_x = new int[vert_count];
vert_y = new int[vert_count];
vert_z = new int[vert_count];
face_v_count = new int[face_count];
faces = new int[face_count][];
face_back = new int[face_count];
face_front = new int[face_count];
gouraud_shade = new int[face_count];
2012-11-25 13:43:36 -05:00
for (int v = 0; v < vert_count; v++) {
2012-11-26 16:37:35 -05:00
vert_x[v] = get_short(data, offset);
2012-11-25 13:43:36 -05:00
offset += 2;
}
for (int v = 0; v < vert_count; v++) {
2012-11-26 16:37:35 -05:00
vert_y[v] = get_short(data, offset);
2012-11-25 13:43:36 -05:00
offset += 2;
}
for (int v = 0; v < vert_count; v++) {
2012-11-26 16:37:35 -05:00
vert_z[v] = get_short(data, offset);
2012-11-25 13:43:36 -05:00
offset += 2;
}
this.vert_count = vert_count;
for (int f = 0; f < face_count; f++)
2012-11-26 16:37:35 -05:00
face_v_count[f] = get_u_byte(data[offset++]);
2012-11-25 13:43:36 -05:00
for (int f = 0; f < face_count; f++) {
2012-11-26 16:37:35 -05:00
face_back[f] = get_short(data, offset);
2012-11-25 13:43:36 -05:00
offset += 2;
if (face_back[f] == 32767)
face_back[f] = num_seq;
}
for (int f = 0; f < face_count; f++) {
2012-11-26 16:37:35 -05:00
face_front[f] = get_short(data, offset);
2012-11-25 13:43:36 -05:00
offset += 2;
if (face_front[f] == 32767)
face_front[f] = num_seq;
}
for (int f = 0; f < face_count; f++) {
2012-11-26 16:37:35 -05:00
int i = get_u_byte(data[offset++]);
2012-11-25 13:43:36 -05:00
if (i == 0)
gouraud_shade[f] = 0;
else
gouraud_shade[f] = num_seq;
}
for (int f = 0; f < face_count; f++) {
2012-11-26 16:37:35 -05:00
faces[f] = new int[face_v_count[f]];
2012-11-25 13:43:36 -05:00
for (int fv = 0; fv < face_v_count[f]; fv++) {
if (vert_count < 256) {
2012-11-26 16:37:35 -05:00
faces[f][fv] = get_u_byte(data[offset++]);
2012-11-25 13:43:36 -05:00
} else {
2012-11-26 16:37:35 -05:00
faces[f][fv] = get_u_short(data, offset);
2012-11-25 13:43:36 -05:00
offset += 2;
}
}
}
this.face_count = face_count;
}
2012-11-26 16:37:35 -05:00
public static int get_u_byte(byte b) {
return (b & 0xff);
}
public static int get_u_short(byte b[], int start) {
return ((b[start] & 0xff) << 8) + (b[start + 1] & 0xff);
}
public static int get_short(byte b[], int start) {
int i = get_u_byte(b[start]) * 256 + get_u_byte(b[start + 1]);
if (i > 32767)
i -= 0x10000;
return i;
}
}
</pre>
2012-11-23 14:26:03 -05:00
2012-11-26 10:07:36 -05:00
== '''Faces''' ==
A '''negative''' face_back or face_front value indicates a '''solid colour''', whereas a '''positive''' value indicates a '''texture'''. The texture is defined by its offset in the client's texture array.
2012-11-25 13:47:29 -05:00
2012-11-26 10:07:36 -05:00
When converting to/from [http://en.wikipedia.org/wiki/Wavefront_.obj_file Wavefront OBJ] format, remember that the OB3 face values are one less than the OBJ face values.