Search Unity

Can we read data from a binary file? Could be used for vertex animation.

Discussion in 'Scripting' started by The-Scripter, Nov 4, 2010.

  1. The-Scripter

    The-Scripter

    Joined:
    Nov 10, 2009
    Posts:
    30
    I was wondering if there was any way to import a binary file format and read its data into a script. A text file would be easier as you can use TextAsset.text, but what if the file is not text?

    The only other way of reading a file is TextAsset.bytes, but I can't find a way to interpret those bytes into any value type (except a String). If this works it could allow us to import a point cache file and use it to animate a mesh.

    I can create a string from the Byte array using this:

    Code (csharp):
    1. //fileHeader is a byte[]
    2. string s = System.Text.ASCIIEncoding.ASCII.GetString(fileHeader)
    However, I have not found a way of turning 4 consecutive bytes (32 bits) into an int. Has anyone done this? If it can't be done then what is the purpose of a byte array and TextAsset.bytes?
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Everything is made from bytes, so they can represent whatever you want. One way is to use System.BitConverter, though it's not endian-aware so you need to account for big-endian and little-endian systems yourself.

    --Eric
     
  3. Vicenti

    Vicenti

    Joined:
    Feb 10, 2010
    Posts:
    664
    This is right off the top of my head so it might not be perfect, but I imagine you'd do something similar to:

    Code (csharp):
    1. function FourBytesToInt( byte : Whatever[] ) : int {
    2.   return parseInt(byte[3]) + parseInt(byte[2] * 256) + parseInt(byte[1]*256*256) + parseInt(byte[0]*256*256*256);
    3. }
    Could be 0,1,2,3 if your endian-ness is the other one.

    Edit: Oh hai, Eric, didn't see you there. Xd
     
  4. The-Scripter

    The-Scripter

    Joined:
    Nov 10, 2009
    Posts:
    30
    Thanks for those comments. I didn't realise we could use BitConverter, but it works perfectly. I didn't have to use the manual method, but that will be a good idea if no other class can do it for me.
     
  5. BernieRoehl

    BernieRoehl

    Joined:
    Jun 24, 2010
    Posts:
    80
    BitConverter works, but is it ever slow! I'm trying to convert a byte array into a series of Vector3's, so I'm doing things like this:

    Code (csharp):
    1. for (var i : int = 0; i < verts.length; +i)
    2. {
    3.   verts[i].x = BitConvert.ToSingle(bytes, i*12);
    4.   verts[i].y = BitConvert.ToSingle(bytes, i*12+4);
    5.   verts[i].z = BitConvert.ToSingle(bytes, i*12+8);
    6. }
    For a 16,625 element array it takes nearly a minute! That means each call to BitConvert.ToSingle() is taking over a millisecond, which seem ridiculous considering what it must be doing (which is not very much).

    Anyone encountered this before? Am I missing something? And are there faster alternatives?

    In C, I would of course just do

    Code (csharp):
    1.  
    2.     verts[i].x = *((float *) &bytes[i*12]);
    3.  
    but I don't think I can do that kind of casting in Unityscript or C#.
     
  6. BernieRoehl

    BernieRoehl

    Joined:
    Jun 24, 2010
    Posts:
    80
    Found a solution:

    Code (csharp):
    1.     var s = new MemoryStream(www.bytes);
    2.     var b = new BinaryReader(s);
    3.  
    4.     var verts = new Vector3[smr.sharedMesh.vertices.length];  // new vertex array
    5.     for (var i : int = 0; i < verts.length; ++i)
    6.     {
    7.         verts[i].x = b.ReadSingle();
    8.         verts[i].y = b.ReadSingle();
    9.         verts[i].z = b.ReadSingle();
    10.     }
    11.    
    12.     b.Close();
    13.     s.Close();
    ... much, much faster. Still no idea why mono's BitConverter is so slow.
     
  7. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    What is "BitConvert.ToSingle"? Using System.BitConverter.ToSingle, I can do over 25000 calls in 1 ms on my computer.

    --Eric