jPCT - a 3d engine for Java => Support => Topic started by: AGP on November 23, 2015, 05:17:47 am

Title: HOB Loader
Post by: AGP on November 23, 2015, 05:17:47 am
Egon, would you be so kind as to write me a quick-and-dirty loader for a file format specified in the following description? I'd do it if I completely understood it. :- )

4B object count OF. 0 in empty files
4B simple offset to vertices/faces - doesn't work all the time. Probably useless...

OF * object header 116B
  16B name
  4B int facegroups offset
  4B int facegroup header offset
  4B int facegroup header 2 offset
  12B zero
  4B int ? 94, 0xD4
  4B int ? 98, 0x100
  4B int ? 9C, 0x104
  4B float ?:
      -bark_moon, cldcar: 1.0
      -sky, e_cor: 0.2
      -wmvwing: 1.25
  12B zero
  5x4B floats ?
  4B int offset before 0xFFFFFFFF header end marker
  6x 4B float ?

OF * facegroup header
  2B number of facegroups NOF
  2B NX ?
  NOF * facegroup/meshdef0 offset {
    4B int ?
    4B int facegroup/meshdef0 offset
  2B NOF again
  2B NX ? 
  NX * offsets + zeros
  NOF * name {
    2B facegroup number
    8B char

  4B 0xFFFFFFFF header end marker

NOF * facegroup/meshdef0 (fg/m0) 132B
  4B int offset to next fg/m0, 0 if there's no next, or in some other circumstances
  4B int offset to prev?
  4B int offset to beginning if this is not first fg/m0?
  4B int offset to end if offset to next = 0
  4B int offset to meshdef1 + 4
  8B zero
  48B 3 * {
    4B float 1.0
    12B zero
  4B int
  3 * 4B float
  3 * 4B float 1.0
  28B zero

NOF * facegroup/meshdef1 96B
  4B int facedef end offset
  20B zero
  4B int vertices used
  4B int ?
  4B zero
  4B int face def offset
  4B int vertex def offset
  52B zero
NOF * face block
  8B zero
  4B int filepos + 4
  4B int face count FC
  FC * face
    4B int face flags
        - bits 0, 1 unknown
        - if bit 2 is set, face has texture coordinates (uv-s)   
        - if bit 3 is set, the face is a quad, otherwise it's a triangle
        - if bit 4 is set, face has separate colors for each vertex
        - if bit 5 is set, face has color
        - if bit 6 is set, face has extra 8 bytes before vertex colors
        - bits 7-10 unknown. higher bits don't seem to be set
    1B int ? 46/49/4B
    1B int ? 51/71
    1B int ? 0C
    1B int face block size divided by 4
        - A = 40B, 9 = 36, etc.
    2B int zero
    2B int material index
    4x 2B vertex indices, relative to the face group. The last index is zero in triangle faces
    if (face has extra 8 bytes) {
        8B extra bytes
    if (face has color) {
        if (face has vertex colors) {
            3/4 * 4B RGBA vertex color
        } else {   
            4B RGBA color
    if (face has texture coordinates) {
        3/4 * {
            2B int horizontal texture coord
            2B int vertical texture coord

  2B int X
  2B int Y
  2B int Z
  2B int ?

Title: Re: HOB Loader
Post by: EgonOlsen on November 23, 2015, 09:12:38 am
Well....no, I can't. I don't have time for that especially since this is some strange format that no other user would benefit from (I assume that this is this Star Trek game spaceship format!?).

Apart from that, I don't see why I should be better in understanding this format than you are. It basically looks like a list of chunks with lots of unknown elements...If somebody reverse engineered this thing, isn't there some loader/converter for it available already?
Title: Re: HOB Loader
Post by: AGP on November 23, 2015, 09:50:00 am
There isn't. Why would you guess Star Trek? At any rate, any format benefits everyone. jpct is a little lacking in loaders, really (most of the time obj does the trick for static objects, but sometimes I run into problems at the exporter end, and others it doesn't cut it for other reasons).

At the very least you'd be better at the jpct end. Beyond that, you've written your share of loaders. I'll try my hand at it when I wake up, then.
Title: Re: HOB Loader
Post by: EgonOlsen on November 23, 2015, 10:02:50 am
I googled for HOB and I found that it's the format of some ship meshes in some Star Trek game. If it's not that, what is it then?
Title: Re: HOB Loader
Post by: AGP on November 23, 2015, 06:36:13 pm
There's a series of late 1990s, early 2000s, games that used it. In this particular case it's Star Wars. LOL
Title: Re: HOB Loader
Post by: AGP on November 26, 2015, 07:39:38 am
Given the following definitions, assuming I'm filling them right (I'm not able to compile it just yet but my main concern is with Java's signed bytes and ints, otherwise it should be right tomorrow morning), how do I build the Object3Ds?

Code: [Select]
class THobFile {
     protected int obj_count;
     protected THobObject[] objects;
     public THobFile() {
objects = new THobObject[2];
     public void setLength(int length) {
THobObject[] newObjects = new THobObject[length];
for (int i = 0; i < length && i < objects.length; i++)
     newObjects[i] = objects[i];
objects = newObjects;
class THobObject {
     byte[] name = new byte[16];
     int face_group_offset, face_group_header_offset, face_group_header2_offset;
     int face_group_count, face_group_count0;
     protected THobFaceGroup[] face_groups;
     public THobObject() {
face_groups = new THobFaceGroup[2];
     public void setLength(int length) {
THobFaceGroup[] newFaces = new THobFaceGroup[length];
for (int i = 0; i < length && i < face_groups.length; i++)
     newFaces[i] = face_groups[i];
face_groups = newFaces;
class THobFaceGroup {
     protected int meshdef1_offset, face_block_end_offset, face_block_offset, vertex_block_offset;
     protected int face_count;
     protected THobFace[] faces;

     protected int vertex_count;
     protected Vector[] vertices;
     public THobFaceGroup() {
faces = new THobFace[2];
     public void setLength(int length) {
THobFace[] newFaces = new THobFace[length];
for (int i = 0; i < length && i < faces.length; i++)
     newFaces[i] = faces[i];
faces = newFaces;
     public void setVerticesLength(int length) {
Vector[] newVertices = new Vector[length];
for (int i = 0; i < length && i < vertices.length; i++)
     newVertices[i] = vertices[i];
vertices = newVertices;
class THobFace {
     protected int flags;
     protected byte b1, b2, b3;
     protected byte bsize;
     protected byte ftype; //3 - tri, 4 - quad
     protected short material_index;
     protected short[] indices = new short[4];
     protected TRGBA[] vertex_colors = new TRGBA[4];
     protected TTexCoord[] tex_coords = new TTexCoord[4];
class TTexCoord {
     protected short u, v;
class Vector {
     protected float x, y, z, unknown;
     public SimpleVector getSimpleVector() {
return new SimpleVector(x, y, z);
Title: Re: HOB Loader
Post by: AGP on November 26, 2015, 07:51:07 am
TRGBA is just an int, by the way.

Code: [Select]
class TRGBA {
     protected int color;
Title: Re: HOB Loader
Post by: EgonOlsen on November 26, 2015, 09:42:19 am
I usually read such stuff and store it in some intermediate data structure from which I then, after reading it all in, create Object3Ds with addTriangle. Another option would be to store in a basic array structure and use Object3D's bulk constructor. raft did that on some occasions, but I usually don't.
Title: Re: HOB Loader
Post by: AGP on November 27, 2015, 08:37:35 pm
OK, I need to triangulate the mesh, now. The first triangle of every square is obviously easy: any three vertices. Of the second I have the first vertex (the unused one). How do I find the other two?
Title: Re: HOB Loader
Post by: EgonOlsen on November 27, 2015, 09:03:53 pm
The other two are shared with the other triangle. If you have all four points of the square and know the order in which they are connected, it's really simple. Just draw it on paper to see for yourself. 5 points on the other...that's a different question. I don't support this either, because it's not trivial anymore.
Title: Re: HOB Loader
Post by: AGP on November 28, 2015, 07:13:40 am
It's simple if you have the edges. Is there a way to figure out the other two without them?
Title: Re: HOB Loader
Post by: EgonOlsen on November 28, 2015, 09:32:54 am
You have to have some edge information somehow. Without it, you can't even build a square. This is usually modelled as an index list that points into the vertex list.