Search Unity

Point Cache reader

Discussion in 'Made With Unity' started by listener, Apr 2, 2012.

  1. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    I needed this reader for my project so i have written pc2 point cache files reader that you can attach to your mesh, setup fps and let it run.

    Right now this is the very early version and its not working on Android but it will soon, till then here is the video of it working and also the code for your viewing and using pleasure.




    Code (csharp):
    1. //
    2. //POINT CACHE READER
    3. //
    4. //Created By: Dejan Omasta
    5. //email: list3ner@gmail.com
    6. //
    7. //=================================================
    8. using UnityEngine;
    9. using System.Collections;
    10. using System.Collections.Generic;
    11. using System.IO;
    12.  
    13. public class PointCacheReader : MonoBehaviour
    14. {
    15.     //
    16.     //POINT CACHE Vs
    17.     //
    18.     public string filePath;
    19.    
    20.     struct PointCacheFile
    21.     {
    22.         public char[] signature;
    23.         public int fileVersion;
    24.         public int numPoints;
    25.         public float startFrame;
    26.         public float sampleRate;
    27.         public int numSamples;
    28.         public List<Vector3> vertexCoords;
    29.     }
    30.    
    31.     PointCacheFile pcFile;
    32.     bool fileParsed = false;
    33.     //
    34.     //VERTEX POS Vs
    35.     //
    36.     public float fps = 24.0f;
    37.     Mesh mesh;
    38.     Vector3[] vertices;
    39.     int counter = 0;
    40.     int curFrame = 0;
    41.     float tempTime = 0.0f;
    42.     float timeMeasure = 0.0f;
    43.    
    44.     // Use this for initialization
    45.     void Start ()
    46.     {
    47.         pcFile = new PointCacheFile();
    48.         ParsePCFile();
    49.        
    50.         timeMeasure = 1 / fps;
    51.         mesh = this.GetComponent<MeshFilter>().mesh;
    52.         vertices = mesh.vertices;
    53.         tempTime = Time.time;
    54.     }
    55.    
    56.     // Update is called once per frame
    57.     void Update ()
    58.     {
    59.    
    60.     }
    61.    
    62.     void FixedUpdate()
    63.     {
    64.         if(Time.time > tempTime + timeMeasure)
    65.         {
    66.             if (fileParsed)
    67.             {
    68.            
    69.                 for (int x = 0; x < vertices.Length; x++)
    70.                 {
    71.                     vertices[x] = pcFile.vertexCoords[counter];
    72.                     counter++;
    73.                 }
    74.                 mesh.vertices = vertices;
    75.                 mesh.RecalculateBounds();
    76.                 mesh.RecalculateNormals();
    77.                 curFrame++;
    78.                 if (curFrame == pcFile.numSamples)
    79.                 {
    80.                     curFrame = 0;
    81.                     counter = 0;
    82.                 }
    83.             }
    84.             tempTime = Time.time;
    85.         }
    86.     }
    87.    
    88.     void ParsePCFile()
    89.     {
    90.         FileStream fs = new FileStream(filePath, FileMode.Open);
    91.         BinaryReader binReader = new BinaryReader(fs);
    92.         //
    93.         //SIGNATURE
    94.         //
    95.         pcFile.signature = new char[12];
    96.         pcFile.signature = binReader.ReadChars(12);
    97.         //
    98.         //FILE VERSION
    99.         //
    100.         pcFile.fileVersion = binReader.ReadInt32();
    101.         //
    102.         //NUMBER OF POINTS
    103.         //
    104.         pcFile.numPoints = binReader.ReadInt32();
    105.         //
    106.         //START FRAME
    107.         //
    108.         pcFile.startFrame = binReader.ReadSingle();
    109.         //
    110.         //SAMPLE RATE
    111.         //
    112.         pcFile.sampleRate = binReader.ReadSingle();
    113.         //
    114.         //NUMBER OF SAMPLES
    115.         //
    116.         pcFile.numSamples = binReader.ReadInt32();
    117.         //
    118.         //GET VERTEX COORDS
    119.         //
    120.         pcFile.vertexCoords = new List<Vector3>();
    121.         for (int i = 0; i < pcFile.numSamples; i++)
    122.         {
    123.             for (int x = 0; x < pcFile.numPoints; x++)
    124.             {
    125.                 Vector3 vPos = new Vector3();
    126.                 vPos.x = binReader.ReadSingle();
    127.                 vPos.y = binReader.ReadSingle();
    128.                 vPos.z = binReader.ReadSingle();
    129.                 pcFile.vertexCoords.Add(vPos);
    130.             }
    131.         }
    132.         fileParsed = true;
    133.     }
    134. }
     
  2. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    The points? Not sure i understand what do you mean by that.
     
  3. yuriythebest

    yuriythebest

    Joined:
    Nov 21, 2009
    Posts:
    1,125
    pcFile.vertexCoords?
     
  4. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    Function ParsePCFile() parses the pc2 file in to PointCacheFile struct and yes all vertices are stored in to pcFile.vertexCoords List in the same order they are stored in pc2 file.
     
  5. kurylo3d

    kurylo3d

    Joined:
    Nov 7, 2009
    Posts:
    1,123
    how long til it works in android!? :) need it bad.
     
  6. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    great work thanks!!
     
  7. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    Thank you.

    Can't promise anything, but i'm planning to do it asap, since i need it too:)
     
  8. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    Here is Android update :) tested and working, this flag is happily running on my phone i don't know for iPhone since i cant test it but i see no reason why it should not work.

    This first PointCacheReader would also work on android the main limitation was deploying point cache file to your phone with the compiled project, i was thinking about making a feature where you put some web address and it downloads extra data like point caches from some web location but guys on #unity3d channel told me of cool way to move files with compiled game and I thank them for that so here is a little modified PointCacheAndReader

    Just few steps you need to do that are different from previous procedure.

    1. When you make your pc2 file change its extension in to *.bytes
    2. Create folder Resources in your project
    3. Drag 'n drop your file with changed extension in to Resources folder

    That's it, only thing you need to do is when you attach this script to your mesh just drag and drop your file from Resources folder to Cache File field in inspector, like you would assign any public variable (Transform, Material etc...)

    And here is the code:


    Code (csharp):
    1. //
    2. //POINT CACHE READER (Works on Android, probably iPhone too:))
    3. //
    4. //Created By: Dejan Omasta
    5. //email: list3ner@gmail.com
    6. //
    7. //=================================================
    8. using UnityEngine;
    9. using System.Collections;
    10. using System.Collections.Generic;
    11. using System.IO;
    12. using System;
    13.  
    14. public class PointCacheAndReader : MonoBehaviour
    15. {
    16.     //
    17.     //POINT CACHE Vs
    18.     //
    19.     public TextAsset cacheFile;
    20.    
    21.     struct PointCacheFile
    22.     {
    23.         public char[] signature;
    24.         public int fileVersion;
    25.         public int numPoints;
    26.         public float startFrame;
    27.         public float sampleRate;
    28.         public int numSamples;
    29.         public List<Vector3> vertexCoords;
    30.     }
    31.    
    32.     PointCacheFile pcFile;
    33.     bool fileParsed = false;
    34.     //
    35.     //VERTEX POS Vs
    36.     //
    37.     public float fps = 24.0f;
    38.     Mesh mesh;
    39.     Vector3[] vertices;
    40.     int counter = 0;
    41.     int curFrame = 0;
    42.     float tempTime = 0.0f;
    43.     float timeMeasure = 0.0f;
    44.    
    45.     // Use this for initialization
    46.     void Start ()
    47.     {
    48.         pcFile = new PointCacheFile();
    49.         Debug.Log("ZETZ - Calling ParsePCFile");
    50.         ParsePCFile();
    51.        
    52.         timeMeasure = 1 / fps;
    53.         mesh = this.GetComponent<MeshFilter>().mesh;
    54.         vertices = mesh.vertices;
    55.         tempTime = Time.time;
    56.     }
    57.    
    58.     // Update is called once per frame
    59.     void Update ()
    60.     {
    61.    
    62.     }
    63.    
    64.     void FixedUpdate()
    65.     {
    66.         if(Time.time > tempTime + timeMeasure)
    67.         {
    68.             if (fileParsed)
    69.             {
    70.            
    71.                 for (int x = 0; x < vertices.Length; x++)
    72.                 {
    73.                     vertices[x] = pcFile.vertexCoords[counter];
    74.                     counter++;
    75.                 }
    76.                 mesh.vertices = vertices;
    77.                 mesh.RecalculateBounds();
    78.                 mesh.RecalculateNormals();
    79.                 curFrame++;
    80.                 if (curFrame == pcFile.numSamples)
    81.                 {
    82.                     curFrame = 0;
    83.                     counter = 0;
    84.                 }
    85.             }
    86.             tempTime = Time.time;
    87.         }
    88.     }
    89.    
    90.     void ParsePCFile()
    91.     {
    92.         MemoryStream ms = new MemoryStream(cacheFile.bytes);
    93.         BinaryReader binReader = new BinaryReader(ms);
    94.         //
    95.         //SIGNATURE
    96.         //
    97.         pcFile.signature = new char[12];
    98.         pcFile.signature = binReader.ReadChars(12);
    99.         //
    100.         //FILE VERSION
    101.         //
    102.         pcFile.fileVersion = binReader.ReadInt32();
    103.         //
    104.         //NUMBER OF POINTS
    105.         //
    106.         pcFile.numPoints = binReader.ReadInt32();
    107.         //
    108.         //START FRAME
    109.         //
    110.         pcFile.startFrame = binReader.ReadSingle();
    111.         //
    112.         //SAMPLE RATE
    113.         //
    114.         pcFile.sampleRate = binReader.ReadSingle();
    115.         //
    116.         //NUMBER OF SAMPLES
    117.         //
    118.         pcFile.numSamples = binReader.ReadInt32();
    119.         //
    120.         //GET VERTEX COORDS
    121.         //
    122.         pcFile.vertexCoords = new List<Vector3>();
    123.         for (int i = 0; i < pcFile.numSamples; i++)
    124.         {
    125.             for (int x = 0; x < pcFile.numPoints; x++)
    126.             {
    127.                 Vector3 vPos = new Vector3();
    128.                 vPos.x = binReader.ReadSingle();
    129.                 vPos.y = binReader.ReadSingle();
    130.                 vPos.z = binReader.ReadSingle();
    131.                 pcFile.vertexCoords.Add(vPos);
    132.             }
    133.         }
    134.         fileParsed = true;
    135.     }
    136. }
    137.  
     
  9. reissgrant

    reissgrant

    Joined:
    Aug 20, 2009
    Posts:
    726
    Nice work!

    Too bad I just spent this past week writing one to put on the asset store.

    Here is mine in action:
     
  10. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    Awesome, I'm sorry if i ruined your plan :( wasn't my intention.

    Id love to hear what was your approach in transferring point cache file to android device, did you did it built in the APK like i did or have u used some other method?
     
  11. reissgrant

    reissgrant

    Joined:
    Aug 20, 2009
    Posts:
    726
    @listener: No problem man! :)

    I originally intended for it to be free, then I spent more and more time on it until it warranted a little payback ;). My vertexpainter was originally free until I started putting tons of time into it and needed a little return from spending time away from my kids.

    Regarding the script:
    At first, I created two byte files: One that translated all the positions and another that was sort of a key to tell which vertices matched up with which, and both sat in the resources folder; this worked on Android.
    On Awake, the object would load the positions and key file into memory and worked great.

    Then I thought the resources folder would get cluttered with a bunch of byte files so I changed it to load the positions into the gameObject itself with a @customEditor script. So now it does that without needing a separate byte file. You just drop your script on the gameObject, press "Load" and it loads the positions onto the game Object.
     
  12. MikeUpchat

    MikeUpchat

    Joined:
    Sep 24, 2010
    Posts:
    1,056
    Will this wont work properly on any mesh that Unity alters on import due to normals or texture coords, as well as the axis system being changed depending on which 3d package the mesh came from? Also using unity normal recalc will give bad results for meshes with any kind of smoothing groups on, will you be able to solve these problems?
     
  13. kurylo3d

    kurylo3d

    Joined:
    Nov 7, 2009
    Posts:
    1,123
    awesome stuff guys! keep up the good work... u rule.. reissgrant you do some awesome work all around :)
     
  14. reissgrant

    reissgrant

    Joined:
    Aug 20, 2009
    Posts:
    726
    Don't want to threadjack but mine accounts for mismatched vertex counts and different transforms and non centered pivots.
    Have not tested with complex normals but shouldn't be hard to figure out.
     
  15. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    Well of course you implemented more options and spent more time on it, i really did this in few hours, most of the time spent finding structure of PC2 files not many docs on that, when i found it it was really quick maybe an hour of coding and testing.

    Interesting approach, so you load it all in array or generic list and transfer it like that.
     
    Last edited: Apr 12, 2012
  16. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    Well here is the thing, unity splits vertices depending on normals, 8 vertices box imported in unity will have 24 vertices, i think this all can be corrected using smoothing. But if your cache file has data for 8 vertices that's a small bump, then you need extra step to check position of vertices in script and those that have same coordinates are actually one vertice and on all of them you can apply same transformation.

    But since i did not have this problem in project i wrote this for i haven't implemented that part at all, and i think if you use smoothing your vertices wont get split at all so no need for it.

    As for coordspace, also possible to do the translation, you can just say x is y and so on also simple thing to implement and as i haven't had need for it in my project haven't implemented it because all meshes are custom made for this project and i have established workflow already so animation is done with idea to be used in unity, if you are using premade stuff animated for different purposes then you need to alter whats assigned to x, y and z.

    Just make your own order out of it, i haven't planned to publish this cache reader as commercial thing on store so haven't implemented user friendly features to all this for you, just wanted to share this so it can help someone as it did me. Possibly if i have time i will implement this stuff.

    If you made the mesh and animation with idea to use it in unity then you should not have any problems with this, if its something not made for that purpose then you need to test it first then possibly make some changes to script.
     
  17. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    That is nice, do you match vertex position and apply same transforms on it?
    I think this one could work with non centered pivots if its all cached like that why not.

    I have tested it for example with bunch of pipes tangled going in all directions and ball animated as it goes trough pipes and as pipe gets thicker where ball passes, that was all rigged and animated in blender, then cached and worked nicely in unity.
     
  18. kurylo3d

    kurylo3d

    Joined:
    Nov 7, 2009
    Posts:
    1,123
    u both rule :)
     
  19. bandingyue

    bandingyue

    Joined:
    Nov 25, 2011
    Posts:
    131
    So Kind of you!

    I have try it.

    It does work.

    I have no need to buy MegaFiers.

    Thank you , you boy is so good !
     
    Last edited: Jun 7, 2012
  20. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    ok i feel like a compleet idiot with an IQ of below zero but... how does this work...? and i don't mean internally, just how do i get this to work :-s
    i exported my mesh with a point cache modifier ontop from max (is that wrong for starters?) and then put you script on it... i even copied over the xml file to my assets folder and gave the script the path... but my flag just sits there all quite doing nothing :-(

    ok so i figured out is for a PC2 file not the xml, but still doesn't do anything?
     
    Last edited: Jun 8, 2012
  21. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    sorry for the bump, but it keeps saying:
     
  22. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    ok stupid me i forgot to put the file name after the path...
    anyway new problem :)
    I made a build and send it to a friend, but he didn't had the flags in or at least not working, so my guess is the PC2 files didn't go into the build?
    is that normal?
     
  23. w00dn

    w00dn

    Joined:
    Apr 28, 2010
    Posts:
    275
    listener, thank you very much for this script. It works perfectly! :)
    I made two small changes to it. I hope you don't mind.

    1. I removed FixedUpdate and replaced it with InvokeRepeating which is started and stopped by OnBecameVisible and OnBecameInvisible , so the whole thing only runs if it's actually visible.

    2. I closed the filestream at the bottom, so you can have several copies of the same object without getting a sharing violation.

    EDIT: 3. Added a var to specify the starting frame of the animation, so you can have for example 3 looping flags next to each other but with an animation offset so they don't look cloned. ;-)

    Code (csharp):
    1. //
    2. //POINT CACHE READER
    3. //
    4. //Created By: Dejan Omasta
    5. //email: list3ner@gmail.com
    6. //
    7. //=================================================
    8. using UnityEngine;
    9. using System.Collections;
    10. using System.Collections.Generic;
    11. using System.IO;
    12.  
    13. public class PointCacheReader : MonoBehaviour
    14. {
    15.     //
    16.     //POINT CACHE Vs
    17.     //
    18.     public string filePath;
    19.    
    20.     struct PointCacheFile
    21.     {
    22.         public char[] signature;
    23.         public int fileVersion;
    24.         public int numPoints;
    25.         public float startFrame;
    26.         public float sampleRate;
    27.         public int numSamples;
    28.         public List<Vector3> vertexCoords;
    29.     }
    30.    
    31.     PointCacheFile pcFile;
    32.     bool fileParsed = false;
    33.     //
    34.     //VERTEX POS Vs
    35.     //
    36.     public float fps = 24.0f;
    37.     Mesh mesh;
    38.     Vector3[] vertices;
    39.     int counter = 0;
    40.     int curFrame = 0;
    41.     public int startFrame = 0;
    42.     float timeMeasure = 0.0f;
    43.    
    44.     // Use this for initialization
    45.     void Start ()
    46.     {
    47.         pcFile = new PointCacheFile();
    48.         ParsePCFile();
    49.         timeMeasure = 1 / fps;
    50.         mesh = this.GetComponent<MeshFilter>().mesh;
    51.         vertices = mesh.vertices;
    52.         curFrame = startFrame;
    53.         counter = vertices.Length * curFrame;
    54.     }
    55.    
    56.     void OnBecameVisible()
    57.     {
    58.         if(!IsInvoking("PlayLoop")  fileParsed) {
    59.             InvokeRepeating("PlayLoop", 0.01f, timeMeasure);
    60.         }
    61.     }
    62.    
    63.     void OnBecameInvisible()
    64.     {
    65.         if(IsInvoking("PlayLoop")) {
    66.             CancelInvoke("PlayLoop");
    67.         }
    68.     }
    69.    
    70.     void PlayLoop()
    71.     {
    72.         for (int x = 0; x < vertices.Length; x++)
    73.         {
    74.             vertices[x] = pcFile.vertexCoords[counter];
    75.             counter++;
    76.         }
    77.         mesh.vertices = vertices;
    78.         mesh.RecalculateBounds();
    79.         mesh.RecalculateNormals();
    80.         curFrame++;
    81.         if (curFrame == pcFile.numSamples)
    82.         {
    83.             curFrame = 0;
    84.             counter = 0;
    85.         }        
    86.     }
    87.    
    88.     void ParsePCFile()
    89.     {
    90.         FileStream fs = new FileStream(filePath, FileMode.Open);
    91.         BinaryReader binReader = new BinaryReader(fs);
    92.         //
    93.         //SIGNATURE
    94.         //
    95.         pcFile.signature = new char[12];
    96.         pcFile.signature = binReader.ReadChars(12);
    97.         //
    98.         //FILE VERSION
    99.         //
    100.         pcFile.fileVersion = binReader.ReadInt32();
    101.         //
    102.         //NUMBER OF POINTS
    103.         //
    104.         pcFile.numPoints = binReader.ReadInt32();
    105.         //
    106.         //START FRAME
    107.         //
    108.         pcFile.startFrame = binReader.ReadSingle();
    109.         //
    110.         //SAMPLE RATE
    111.         //
    112.         pcFile.sampleRate = binReader.ReadSingle();
    113.         //
    114.         //NUMBER OF SAMPLES
    115.         //
    116.         pcFile.numSamples = binReader.ReadInt32();
    117.         //
    118.         //GET VERTEX COORDS
    119.         //
    120.         pcFile.vertexCoords = new List<Vector3>();
    121.         for (int i = 0; i < pcFile.numSamples; i++)
    122.         {
    123.             for (int x = 0; x < pcFile.numPoints; x++)
    124.             {
    125.                 Vector3 vPos = new Vector3();
    126.                 vPos.x = binReader.ReadSingle();
    127.                 vPos.y = binReader.ReadSingle();
    128.                 vPos.z = binReader.ReadSingle();
    129.                 pcFile.vertexCoords.Add(vPos);
    130.             }
    131.         }
    132.        
    133.         fileParsed = true;
    134.         fs.Close();
    135.     }
    136. }
     
    Last edited: Jun 10, 2012
  24. UnityCoder

    UnityCoder

    Joined:
    Dec 8, 2011
    Posts:
    534
    Thank u very much all of u for providing such a very good script.

    I tried it in my sample projects, but i m having some problem. My animation is not working properly. I m sure that its not script's problem. Problem is from point cache file; which made by teammate. So i request u can u please provide me also that fbx with that point cache file for reference.

    Thanks in advance.
     
  25. erek

    erek

    Joined:
    Jun 14, 2012
    Posts:
    4
    i keep getting the follow error:


    EndOfStreamException: Failed to read past end of stream.
    System.IO.BinaryReader.FillBuffer (Int32 numBytes)
    System.IO.BinaryReader.ReadSingle ()
    PointCacheReader.ParsePCFile () (at Assets/PointCacheReader.cs:252)
    PointCacheReader.Start () (at Assets/PointCacheReader.cs:95)
     
  26. erek

    erek

    Joined:
    Jun 14, 2012
    Posts:
    4
    for anyone using Autodesk 3ds max 2013 please get the latest update because there is a bug with the PC2 export involving unicode encoding...

    KellyM
    06-01-2012, 07:56 PM
    This should be fixed in the new 3ds Max 2013 Product Update 2, please give it a run.

    http://www.autodesk.com/3dsmax-updates
     
  27. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    Cool i like the changes i'm glad you find it useful and can expand on it.

    So people don't get stuck i have made explanation of the general workflow and i have put for download unity package for android and unity project for desktop version of the script on my site.

    http://www.listener.com.ba/thepage/2012/04/02/unity3d-pointcache-pc2-file-reader/

    So i hope this can resolve any further issues.

     
  28. EpiKiwy

    EpiKiwy

    Joined:
    May 3, 2012
    Posts:
    4
    Hi !

    I have some trouble using this script, my mesh become competely deform..
    I don't know if it can come from here but i use a SkinnedMeshRenderer instead the MeshFilter.

    Moreover with this version on script i have some error at runtime "Argument out of range" on this part

    Code (csharp):
    1.  
    2. for (int x = 0; x < vertices.Length; x++)
    3. {
    4.      vertices[x] = pcFile.vertexCoords[counter];
    5.      counter++;
    6.  }
    7.  
    It's counter which is out of range.
    So i replace

    Code (csharp):
    1. x < vertices.Length
    by
    Code (csharp):
    1. x < pcFile.numPoints
    In fact pcFile.numPoints is the number of point per sample, and there is less point in each sample of my pc2 file than in my mesh...

    but it doesn't work better. Any idea about this ?
    Thank you for all.
     
    Last edited: Jun 21, 2012
  29. erek

    erek

    Joined:
    Jun 14, 2012
    Posts:
    4
    i have had similar problems and had to make some adjustments to the script...


    Code (csharp):
    1.  void PlayLoop()
    2.  
    3.     {
    4.  
    5.         for (int x = 0; x < vertices.Length; x++)
    6.  
    7.         {
    8.  
    9.             if( counter<pcFile.vertexCoords.Count) {vertices[x] = pcFile.vertexCoords[counter];}
    10.  
    11.             counter++;
    12.  
    13.         }
    14.  
    15.         mesh.vertices = vertices;
    16.        
    17.         //mesh.Optimize();
    18.        
    19.  
    20.         mesh.RecalculateBounds();
    21.  
    22.        mesh.RecalculateNormals();
    23.  
    24.         curFrame++;
    25.  
    26.         if (curFrame == endFrame /*pcFile.numSamples*/ )
    27.  
    28.         {
    29.  
    30.            curFrame = startFrame;
    31.  
    32.             counter = vertices.Length * startFrame;
    33.  
    34.         }        
    35.  
    36.     }
    Code (csharp):
    1.  pcFile.vertexCoords = new List<Vector3>();
    2.  
    3.         for (int i = 0; i < pcFile.numSamples; i++)
    4.  
    5.         {
    6.  
    7.             for (int x = 0; x < pcFile.numPoints; x++)
    8.  
    9.             {
    10.  
    11.                 Vector3 vPos = new Vector3();
    12.                  try
    13.                 {
    14.                 vPos.x = binReader.ReadSingle() *.010f;
    15.  
    16.                 vPos.y = binReader.ReadSingle()*.010f;
    17.  
    18.                 vPos.z = binReader.ReadSingle()*.010f;
    19.  
    20.                 pcFile.vertexCoords.Add(vPos);
    21.                 }
    22.                      catch(EndOfStreamException e)
    23.                 {
    24.                     Debug.Log (                        e.GetType().Name);
    25.                 }
    26.  
    27.             }
    28.  
    29.         }
    30.  
     
  30. UnityCoder

    UnityCoder

    Joined:
    Dec 8, 2011
    Posts:
    534
    @listener, Thank u very much for gave us sample project file for point cache reader. I downloaded ur project and put my model in that project. I followed ur instruction step by step but i didnt get proper result (my object getting distorted). I exported that fbx from 3ds max 2011. Can u tell me if there is any special setting into max? or please guide me how to export .pc2 file from max.
     
  31. MikeUpchat

    MikeUpchat

    Joined:
    Sep 24, 2010
    Posts:
    1,056
    Thanks for the script but I to just get a mess with this, I think the problem lies in this script will only work on meshes where Unity doesn't change the vertex count due to smoothing or uv seams in the original mesh, so will only work on very basic and simple objects such as the example flag.
     
  32. EpiKiwy

    EpiKiwy

    Joined:
    May 3, 2012
    Posts:
    4
    I look for resolve the problem of unity smoothing. I write a script which parse all vertex of my mesh and put in the same list each vertex with the same coordonates. I found the right VertexCount.
    After that i need to link each vertex of point cache sample and rely them to the right mesh struct. But for now the rotation and scale of this two point system are different, so i'm not able to rely them yet.

    For people who search to morph single object there are an easier solution. On this page (http://unitycoder.com/blog/2011/08/15/wip-3dsmax-to-unity-mesh-maker/) there is a 3dsmax exporter which permit you to export a unity js file in order to create the mesh at runtime, with this method no more vertex count problem. You can animate your model with the point cache reader, i test it and it work properly.
     
  33. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    Only thing i can remmember that can be issue with 3ds max is that it has two point cache modifiers one i think exports local space and other (i think it has WSM in name) exports in world space. I don't know will this fix the problem but it costs nothing to try... also make sure your model is in triangles before animation and caching takes place otherwise unity will do that for you and you will not have same number of verts as in your 3d app.


    This script depends that your model after it is imported in to unity has the same number of verts as in your 3d app. Since this is the thing that creates most problems in more complex models because unity can split your verts in to more i will try to fix this in script and publish it along with tutorial that will show workflow. I am not promising anything really fast but right now i have some free time so i will try to spend it on improving point cache reader.
     
  34. MikeUpchat

    MikeUpchat

    Joined:
    Sep 24, 2010
    Posts:
    1,056
    I am sorry but that script will not help in the slightest for meshes with smoothing groups or uv seams, there is no way you can have a mesh in Unity with the same number of vertices as in Max if you have any kind of smoothing or complex uv mapping as Unity and Max store their mesh data in two very different ways. If you want to do point cache or morphing then you really are better off spending a little money and getting a system of the store that works.
     
  35. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    I'm sure commercial solutions are more elaborate since they are built for general use and we are aware of their existence, this one is not so if it can help someone that's cool.

    Do other systems that you say are commercial can support this type of animation when unity3d splits verts, i have seen megafiers demo also with a flag as a simple object, nothing complex so just wondering since i have never used it? it would be nice to know from someone that already uses it?


    On the other issue i have spent some time with this script now and the main and only problem now is that it seems when unity3d splits your meshes vertices it does also change vertex ordering (at least from what i have seen so far) so it is impossible to actually apply point cache because vertex are not in the same order at all. I still need to check and recheck this but this is so far how it looks.

    So for now, if you want to use this script on your models first and the most important thing is the same number of verts as in your 3d app.

    If someone has any ideas on the matter please share anything helps.
     
  36. reissgrant

    reissgrant

    Joined:
    Aug 20, 2009
    Posts:
    726
    The way I solved this was to store each position in an array and match them to the imported verts. It's not ideal, but it works and was the only way I could get it to work every time.
     
  37. SpookyCat

    SpookyCat

    Joined:
    Jan 25, 2010
    Posts:
    3,765
    Just seen the thread and as one of the 'Commercial solutions' and seeing as you were wondering if it works I did a very simple video of a multi material with smoothing groups to show it working.
    Chris
     
  38. RandAlThor

    RandAlThor

    Joined:
    Dec 2, 2007
    Posts:
    1,293
    Hello Listener,

    i just found this thread and want to ask if this will make it possibel to use this program http://www.brekel.com/?page_id=854 with your point cache reader so we can make facial animations with it?

    He has a free version to try and there is a a file to download with some examples in fbx format and he has a unity streaming script for this.
     
  39. MikeUpchat

    MikeUpchat

    Joined:
    Sep 24, 2010
    Posts:
    1,056
    Dont think point cache is much use for the that system you will end up with massive files, it is much better suited to bones and to morphs and Brekel has pipelines for both systems so with a good morphing system can finally get really good face animations on mobile devices instead of very poor bone based face animations and a limit of 2 bone influences per vertex.
     
  40. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    I was thinking about something like that as a solution, to map all vert positions at start and also to make third array that would actually say, 1 is 24, 2 is 55 etc :) it does not sound elegant :) but that's something from the top of my head. I am planning to do this next week and test it to see if it works... if it does yay it could be final solution:)

    @SpookyCat

    Thank you for your video i can see it works really well, you did not have to go thru all trouble of making a video, because your plugins are really looking good and it can be clear to anyone that person or persons behind them have great experience in 3D math and programming not to mention inter workings of unity3D so to any sane person a word would be enough, but video is swell :)

    @RandAlThor
    At this point requirement is that your model has the same number of verts in the program where you make your pc2 and in Unity3D if you can accomplish that then i don't see why it would not work. But as Mike wrote, its important to keep in mind size of your point cache file don't overkill it.

    As i am still working on improving this script i hope by the end of the next week i can publish some progress and bypass the problem of Unity3D splitting verts and rearranging indexes...

    I wish you all the best, and please post if you succeed it would be nice to hear you did it.
     
  41. gizmo1990

    gizmo1990

    Joined:
    Jul 12, 2012
    Posts:
    32
    @listener and reissgrant, guys do either of your programs allow me to import morphs from 3dsmax?
     
  42. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    187
    Sorry but this script does not, I don't know about ressigrant's.
     
  43. MikeUpchat

    MikeUpchat

    Joined:
    Sep 24, 2010
    Posts:
    1,056
    @gizmo1990 For easy exporting of morphs from 3ds max I use SpookyCat's MegaFiers.
     
  44. Cascho01

    Cascho01

    Joined:
    Mar 19, 2010
    Posts:
    1,347
    The scripts work nice on basic objects.
    I tried to use it with a skinned mesh (biped with motioncapture-file) and get wrong rendering results.
    Before exporing from 3dsmax I deleted skin modifier, but it doesn´t help.

    Any ideas?
     
  45. Cascho01

    Cascho01

    Joined:
    Mar 19, 2010
    Posts:
    1,347
    I modified the first script so that you now can run it by defining the current frame .

     
  46. Cascho01

    Cascho01

    Joined:
    Mar 19, 2010
    Posts:
    1,347
    Is anyone able to write an editor-script so that we can write the stream into a builtin-array?
    Then we can include the array in the built and don´t have to separately deliver the pointcache file which is often very large.

    Thanks!
     
  47. w00dn

    w00dn

    Joined:
    Apr 28, 2010
    Posts:
    275
    hey guavaman, i haven't tested your script, but i attached a testmodel with a pointcache file of a simple loopable flag. maybe it helps.
     

    Attached Files:

  48. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    Hi! Thanks for sending that. It did help and it made me realize that the poster in the other thread I was helping was using the wrong code. Listener already made a version that uses a TextAsset and it works perfectly. I didn't realize that. Sorry. No need to post a duplicate solution.
     
    Last edited: Sep 27, 2012
  49. anyuanlzh

    anyuanlzh

    Joined:
    Sep 5, 2011
    Posts:
    2
    hello! I know your script is prefect. But the vertex count of FBX model is increased, when it impored to unity. So "mesh.vertices != pcFile.numPoints".
    It does't work, when run. vertices increase, why?
     
  50. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    First make sure you have optimize mesh disabled in the mesh importer. Unity duplicates vertices for a number of reasons in hard to predict ways. For example, if a UV has a cut seam containing that vertex is, it will duplicate it. I think it also does it for normal edges. Some junctions like star junctions in your mesh (say the top/bottom of a sphere) can potentially be duplicated once for each face connected to it. I ran into this problem when trying to write a vertex color importer from Maya. I spent a lot of time trying to reverse engineer Unity's formula for duplicating verts, but I never did get it exactly -- there were always situations on models that would have even more duplicates than I could account for. So, short answer is, there's no way I know of to force Unity to keep the mesh exactly the same as in your modeling program and there's no concrete way of associating the new duplicated verts to the old short of comparing positions. I may be wrong, but I never found a way.

    http://answers.unity3d.com/questions/37435/why-is-unity-got-more-vertices-than-3dsmax.html
     
    Last edited: Nov 1, 2012