diff --git a/OB3.mediawiki b/OB3.mediawiki index 2db3570..f0ce71d 100644 --- a/OB3.mediawiki +++ b/OB3.mediawiki @@ -4,33 +4,85 @@ Work in progress. This page refers to .ob3, a custom format for 3D models created by Jagex. It is used by the RuneScape Classic engine. - [Unsigned Short] vertex_count - [Unsigned Short] face_count - - for (int i = 0; i < vertex_count; i++) - [Signed Short] vert_x - for (int i = 0; i < vertex_count; i++) - [Signed Short] vert_z - for (int i = 0; i < vertex_count; i++) - [Signed Short] vert_y - - for (int i = 0; i < face_count; i++) - [Unsigned Byte] face_vert_count - for (int i = 0; i < face_count; i++) - [Signed Short] face_back - for (int i = 0; i < face_count; i++) - [Signed Short] face_front - for (int i = 0; i < face_count; i++) - [Unsigned Byte] Boolean. Gourad shading? - - for (int i = 0; i < face_count; i++) { - for (int j = 0; j < face_vert_count[i]; j++) { - if (vertex_count < 256) - [Unsigned Byte] Unknown - else - [Unsigned Short] Unknown - } - } +
+import util.Data;
+
+public class Ob3Model {
+	public int faceCount;
+	public int vertexCount;
+
+	public int faceVertexCount[];
+	public int faceBack[];
+	public int faceFront[];
+	public int verticesX[];
+	public int verticesZ[];
+	public int verticesY[];
+
+	private static final int trigger = 0xbc614e;
+
+	public Ob3Model(byte data[], int position) {
+		int vertexCount = Data.readInt16(data, position);
+		position += 2;
+		int faceCount = Data.readInt16(data, position);
+		position += 2;
+
+		verticesX = new int[vertexCount];
+		verticesY = new int[vertexCount];
+		verticesZ = new int[vertexCount];
+
+		faceBack = new int[faceCount];
+		faceFront = new int[faceCount];
+		faceVertexCount = new int[faceCount];
+
+		for (int i = 0; i < vertexCount; i++) {
+			verticesX[i] = Data.readSignedInt16(data, position);
+			position += 2;
+		}
+
+		for (int i = 0; i < vertexCount; i++) {
+			verticesZ[i] = Data.readSignedInt16(data, position);
+			position += 2;
+		}
+
+		for (int i = 0; i < vertexCount; i++) {
+			verticesY[i] = Data.readSignedInt16(data, position);
+			position += 2;
+		}
+
+		for (int i = 0; i < faceCount; i++)
+			faceVertexCount[i] = data[position++] & 0xff;
+
+		for (int i = 0; i < faceCount; i++) {
+			faceBack[i] = Data.readSignedInt16(data, position);
+			position += 2;
+			if (faceBack[i] == 32767)
+				faceBack[i] = trigger;
+		}
+
+		for (int i = 0; i < faceCount; i++) {
+			faceFront[i] = Data.readSignedInt16(data, position);
+			position += 2;
+			if (faceFront[i] == 32767)
+				faceFront[i] = trigger;
+		}
+
+		position += faceCount - 1;
+
+		for (int i = 0; i < faceCount; i++) {
+			for (int j = 0; j < faceVertexCount[i]; j++) {
+				if (vertexCount < 256) {
+					position++;
+				} else {
+					Data.readInt16(data, position);
+					position += 2;
+				}
+			}
+		}
+
+		this.vertexCount = vertexCount;
+		this.faceCount = faceCount;
+	}
+}
== '''Face sides''' ==