Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (489)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (555)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Question about reading Milkshape 3D models.  (Read 883 times)
0 Members and 1 Guest are viewing this topic.
Offline richared

Junior Newbie





« Posted 2005-07-29 14:40:30 »

Hey, I have a little problem with reading a binary file. Maybe someone can help me? I hope this topic is OK on this board.

The thing is, I am trying to read a Milkshape ms3d file. I have a C script that does it, but I want to try to port it to Java. I have tried to just read the header so far, and I allready have a problem. In C, the header is read like this. There is a lot more, off course, but I only focus on the header first in hopes of getting that right means the rest will follow:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
// Define the struct of the header first:
typedef struct MS3DHeader
{
   char ID[10];
   int version;
}MS3DHEADER;

// Read the whole file into a byte buffer (some code omitted):
byte *pBuffer = malloc(fileSize);
fread(pBuffer, fileSize, 1, file );

// Set a pointer to the buffer:
const byte *pPtr = pBuffer;

// Read the header and move the pointer
MS3DHEADER *pHeader = ( MS3DHEADER* )pPtr;
pPtr += sizeof( MS3DHEADER );

// Now, id and version are accesible through:
pHeader->ID; pHeader->version;


This is the gist of it. I tried to read the file in Java using RandomAccessFile in this way:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
// Define a nested class for the header inside the reader class
private final class Ms3dHeader {
    private char[] id;
    private int version;
       
    private Ms3dHeader() {
        id = new char[10];
    }
       
    private String idStr() {
        return new String(id);
    }
}

// Read the header (some code omitted):
file = new RandomAccessFile(filename, "r");

Ms3dHeader head = new Ms3dHeader();
for(int i = 0; i < head.id.length; i++) {
    head.id[i] = (char) ((byte)file.read());
}

head.version = file.readInt();

System.out.println("Head id: " + head.idStr());
System.out.println("Head ver: " + head.version);


Printout is:
Head id: MS3D000000
Head ver: 67108864

Id is correct, but the version is wrong. It should be 4, but as you can see it is 67108864, which is 4 << 24. The readInt() method reads 4 bytes as ints and adds them: (b1 << 24) + (b2 << 16) + (b3 << Cool + b4. And sure enough: When i read the proper 4 bytes from the file, I get 4 0 0 0.

So my question is this: How can I read the int from the file properly, indeed, how can I read the rest properly when int seems to be wrong? The C code apparently gets it right, but I can't see it being done any other way there. The integer should take up 4 bytes in the C reading as well (at least, it does on my machine). Am I just not understanding the C code properly here or am I reading the file wrong in Java?

I also tried readChar() for the ID, but that also became wrong, so I had to read bytes and convert, and a char is generally 2 bytes (last time I checked). And I also know the byte after 4 should not be 0, because that number is part of an unsigned short representing the number of vertices in the model, and that is not 0.

If anyone have any suggestions / alternate ways of reading, it would be appreciated.

Thanks alot,
Richared

In theory, there is no difference between theory and practice. In practice, there is a big difference.
Offline anarchotron

Junior Member




...precious bodily fluids.


« Reply #1 - Posted 2005-07-29 17:02:50 »

Java likes to read things in in Big endian byte ordering.  Your PC is Little  endian ordered.

Here's the doc for readInt()

Quote
public final int readInt()
                  throws IOException

    Reads a signed 32-bit integer from this file. This method reads 4 bytes from the file, starting at the current file pointer. If the bytes read, in order, are b1, b2, b3, and b4, where 0 <= b1, b2, b3, b4 <= 255, then the result is equal to:

     (b1 << 24) | (b2 << 16) + (b3 << Cool + b4
 

Basically you need to swap every 2 bytes on input.  I've done this myself but not in a very clean way.  Some expert here might know of a standard way of throwing Java into little endian mode, or some kind of Reader/Input class that does it for you.



Offline richared

Junior Newbie





« Reply #2 - Posted 2005-07-29 19:08:16 »

Thanks. That really helped.

In case anyone else has this problem, I did some research on the net and found this useful site:

http://mindprod.com/jgloss/endian.html

-r

In theory, there is no difference between theory and practice. In practice, there is a big difference.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline anarchotron

Junior Member




...precious bodily fluids.


« Reply #3 - Posted 2005-07-29 21:07:10 »

Heck, that is really useful.

His code is similar to mine, maybe a bit cleaner.  I like the history section.  I'm definitely a Blefuscudians (big-endian).  This is how I comprehend binary numbers, and I suppose most people do as well.

The ByteBuffer trick is neat but seems a bit, uh, clunky.  Not to mention potentially expensive looking to a C++ programmer. Smiley

OTOH When I use Milkshape I just export to wavefront OBJ and read those into my app Smiley
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Nickropheliac (12 views)
2014-08-31 22:59:12

TehJavaDev (23 views)
2014-08-28 18:26:30

CopyableCougar4 (27 views)
2014-08-22 19:31:30

atombrot (40 views)
2014-08-19 09:29:53

Tekkerue (38 views)
2014-08-16 06:45:27

Tekkerue (34 views)
2014-08-16 06:22:17

Tekkerue (24 views)
2014-08-16 06:20:21

Tekkerue (34 views)
2014-08-16 06:12:11

Rayexar (72 views)
2014-08-11 02:49:23

BurntPizza (47 views)
2014-08-09 21:09:32
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!