Guest User

Untitled

a guest
Jul 28th, 2014
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 22.99 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.IO;
  4. using System.Collections.Generic;
  5. using System;
  6. using System.Text;
  7.  
  8. public struct StudioModelBone
  9. {
  10.     public string   name;
  11.     public int      parent;
  12.     public int      flags;
  13.     public int[]    boneController;
  14.     public float[]  value;
  15.     public float[]  scale;
  16.     public string   path;
  17. }
  18.  
  19. public class StudioModel
  20. {
  21.     private string              m_name;
  22.     private string[]            m_meshPartNames;    // [part]
  23.     private Mesh[][]            m_meshes;           // [part, mesh]
  24.     private Material[][][]      m_meshMaterials;    // [part, mesh, submesh]
  25.     private Material[]          m_materials;        // [textureId]
  26.     private Texture[]           m_textures;         // [textureId]
  27.     private AnimationClip[]     m_animations;       // [animation]
  28.     private AnimationClip[]     m_boneControllers;  // [controller]
  29.     private StudioModelBone[]   m_bones;            // [bone]
  30.  
  31.     public  string              Name
  32.     {
  33.         get
  34.         {
  35.             return m_name;
  36.         }
  37.     }
  38.     public  string[]            MeshPartNames
  39.     {
  40.         get
  41.         {
  42.             return m_meshPartNames;
  43.         }
  44.     }
  45.     public  int                 MeshPartCount
  46.     {
  47.         get
  48.         {
  49.             return m_meshes.Length;
  50.         }
  51.     }
  52.     public  Mesh[][]            Meshes
  53.     {
  54.         get
  55.         {
  56.             return m_meshes;
  57.         }
  58.     }
  59.     public  Material[][][]      Materials
  60.     {
  61.         get
  62.         {
  63.             return m_meshMaterials;
  64.         }
  65.     }
  66.     public  AnimationClip[]     Animations
  67.     {
  68.         get
  69.         {
  70.             return m_animations;
  71.         }
  72.     }
  73.     public  StudioModelBone[]   Bones
  74.     {
  75.         get
  76.         {
  77.             return m_bones;
  78.         }
  79.     }
  80.     public  int                 BoneCount
  81.     {
  82.         get
  83.         {
  84.             return m_bones.Length;
  85.         }
  86.     }
  87.  
  88.     public              StudioModel(string filePath)
  89.     {
  90.         Read(filePath);
  91.     }
  92.  
  93.     public  void        Read(string filePath)
  94.     {
  95.         FileStream      stream;
  96.         string          directory, file;
  97.         int             textureIndex, groupCount;
  98.         string          path;
  99.         byte[]          modelBytes, textureBytes;
  100.         byte[][]        groupBytes;
  101.  
  102.         file        = Path.GetFileNameWithoutExtension(filePath);
  103.         directory   = Path.GetDirectoryName(filePath);
  104.         stream      = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  105.         modelBytes  = new byte[stream.Length];
  106.        
  107.         stream.Read(modelBytes, 0, modelBytes.Length);
  108.         stream.Close();
  109.         stream.Dispose();
  110.        
  111.         m_name          = ByteArrayUtils.ReadASCIIString(modelBytes, 8, 64);
  112.         textureIndex    = BitConverter.ToInt32(modelBytes, 184);
  113.  
  114.         if(textureIndex == 0)
  115.         {
  116.             path = new StringBuilder(directory).Append(Path.DirectorySeparatorChar).Append(file).Append("t.mdl").ToString();
  117.  
  118.             if(File.Exists(path))
  119.             {
  120.                 stream          = new FileStream(path, FileMode.Open, FileAccess.Read);
  121.                 textureBytes    = new byte[stream.Length];
  122.                 stream.Read(textureBytes, 0, textureBytes.Length);
  123.                 stream.Close();
  124.                 stream.Dispose();
  125.             }
  126.             else
  127.             {
  128.                 textureBytes = null;
  129.             }
  130.         }
  131.         else
  132.         {
  133.             textureBytes = modelBytes;
  134.         }
  135.  
  136.         groupBytes  = null;
  137.         groupCount  = BitConverter.ToInt32(modelBytes, 172);
  138.  
  139.         if(groupCount != 0)
  140.         {
  141.             groupBytes = new byte[groupCount - 1][];
  142.  
  143.             for(int i = 0; i < groupCount - 1; i++)
  144.             {
  145.                 path = new StringBuilder(directory).Append(Path.DirectorySeparatorChar).Append(file).Append((i + 1).ToString("00")).Append(".mdl").ToString();
  146.  
  147.                 if(File.Exists(path))
  148.                 {
  149.                     stream          = new FileStream(path, FileMode.Open, FileAccess.Read);
  150.                     groupBytes[i]   = new byte[stream.Length];
  151.                     stream.Read(groupBytes[i], 0, groupBytes[i].Length);
  152.                     stream.Close();
  153.                     stream.Dispose();
  154.                 }
  155.                 else
  156.                 {
  157.                     groupBytes[i] = null;
  158.                 }
  159.             }
  160.         }
  161.  
  162.         ReadBones(modelBytes);
  163.         ReadAnimations(modelBytes, groupBytes);
  164.         ReadControllers(modelBytes);
  165.         ReadTextures(textureBytes);
  166.         ReadMeshes(modelBytes, textureBytes);
  167.     }
  168.     private void        ReadBones(byte[] modelBytes)
  169.     {
  170.         int         numBones, boneIndex, parentBone;
  171.         string      path;
  172.  
  173.         numBones    = BitConverter.ToInt32(modelBytes, 140);
  174.         boneIndex   = BitConverter.ToInt32(modelBytes, 144);
  175.         m_bones     = new StudioModelBone[numBones];
  176.  
  177.         for(int b = 0; b < numBones; b++)
  178.         {
  179.             m_bones[b]                  = new StudioModelBone();
  180.             m_bones[b].parent           = BitConverter.ToInt32(modelBytes, boneIndex + 32 + b * 112);
  181.             m_bones[b].flags            = BitConverter.ToInt32(modelBytes, boneIndex + 36 + b * 112);
  182.             m_bones[b].boneController   = ByteArrayUtils. ReadIntArray(modelBytes, boneIndex + 40 + b * 112, 6);
  183.             m_bones[b].value            = ByteArrayUtils.ReadFloatArray(modelBytes, boneIndex + 64 + b * 112, 6);
  184.             m_bones[b].scale            = ByteArrayUtils.ReadFloatArray(modelBytes, boneIndex + 88 + b * 112, 6);
  185.            
  186.             m_bones[b].name             = new StringBuilder("#Bone").Append(b).Append(" (")
  187.                 .Append(ByteArrayUtils.ReadASCIIString(modelBytes, boneIndex + b * 112, 32)).Append(")").ToString();
  188.  
  189.             parentBone  = m_bones[b].parent;
  190.             path        = m_bones[b].name;
  191.  
  192.             while(parentBone != -1)
  193.             {
  194.                 path        = m_bones[parentBone].name + '/' + path;
  195.                 parentBone  = m_bones[parentBone].parent;
  196.             }
  197.  
  198.             m_bones[b].path = path;
  199.         }
  200.     }
  201.     private void        ReadAnimations(byte[] modelBytes, byte[][] groupBytes)
  202.     {
  203.         int                 sequenceGroupIndex, sequenceGroup, sequenceGroupData, animationIndex, sequenceIndex,
  204.                             animationOffsetIndex, boneAnimationIndex, animationValue, k,
  205.                             numSequences, numFrames, numBones;
  206.         ushort[]            animOffset;
  207.         byte                numValid, numTotal;
  208.         byte[]              bytes;
  209.         float               fps, frame;
  210.         string              path;
  211.         Keyframe[]          xPositionKeys, yPositionKeys, zPositionKeys, xRotationKeys, yRotationKeys, zRotationKeys, wRotationKeys;
  212.         Vector3             eulerRotation, position;
  213.         Quaternion          rotation;
  214.  
  215.         numBones            = BitConverter.ToInt32(modelBytes, 140);
  216.         numSequences        = BitConverter.ToInt32(modelBytes, 164);
  217.         sequenceIndex       = BitConverter.ToInt32(modelBytes, 168);
  218.         sequenceGroupIndex  = BitConverter.ToInt32(modelBytes, 176);
  219.         m_animations        = new AnimationClip[numSequences];
  220.  
  221.         for(int s = 0; s < numSequences; s++)
  222.         {
  223.             fps                 = BitConverter.ToSingle(modelBytes, sequenceIndex + 32 + s * 176);
  224.             numFrames           = BitConverter.ToInt32(modelBytes, sequenceIndex + 56 + s * 176);
  225.             sequenceGroup       = BitConverter.ToInt32(modelBytes, sequenceIndex + 156 + s * 176);
  226.             sequenceGroupData   = BitConverter.ToInt32(modelBytes, sequenceGroupIndex + 100 + sequenceGroup * 104);
  227.             animationIndex      = BitConverter.ToInt32(modelBytes, sequenceIndex + 124 + s * 176);
  228.            
  229.             m_animations[s]         = new AnimationClip();
  230.             m_animations[s].name    = ByteArrayUtils.ReadASCIIString(modelBytes, sequenceIndex + s * 176, 32);
  231.  
  232.             if(sequenceGroup == 0)
  233.             {
  234.                 animationOffsetIndex    = sequenceGroupData + animationIndex;
  235.                 bytes                   = modelBytes;
  236.             }
  237.             else
  238.             {
  239.                 animationOffsetIndex    = animationIndex;
  240.                 bytes                   = groupBytes[sequenceGroup - 1];
  241.  
  242.                 if(bytes == null) // файл не был найден
  243.                 {
  244.                     continue;
  245.                 }
  246.             }
  247.  
  248.             for(int b = 0; b < numBones; b++, animationOffsetIndex += 12)
  249.             {
  250.                 animOffset      = ByteArrayUtils.ReadUshortArray(bytes, animationOffsetIndex, 6);
  251.                 xPositionKeys   = new Keyframe[numFrames];
  252.                 yPositionKeys   = new Keyframe[numFrames];
  253.                 zPositionKeys   = new Keyframe[numFrames];
  254.                 xRotationKeys   = new Keyframe[numFrames];
  255.                 yRotationKeys   = new Keyframe[numFrames];
  256.                 zRotationKeys   = new Keyframe[numFrames];
  257.                 wRotationKeys   = new Keyframe[numFrames];
  258.  
  259.                 position        = Vector3.zero;
  260.                 eulerRotation   = Vector3.zero;
  261.                 rotation        = Quaternion.identity;
  262.  
  263.                 for(int f = 0; f < numFrames; f++)
  264.                 {
  265.                     // Position
  266.                     for(int j = 0; j < 3; j++)
  267.                     {
  268.                         position[j] = m_bones[b].value[j];
  269.            
  270.                         if(animOffset[j] != 0)
  271.                         {
  272.                             boneAnimationIndex  = animationOffsetIndex + animOffset[j];
  273.                             numValid            = bytes[boneAnimationIndex];
  274.                             numTotal            = bytes[boneAnimationIndex + 1];
  275.                            
  276.                             k = f;
  277.                            
  278.                             while (numTotal <= k)
  279.                             {
  280.                                 k -= numTotal;
  281.                                 boneAnimationIndex += (numValid + 1) * 2;
  282.                                 numValid            = bytes[boneAnimationIndex];
  283.                                 numTotal            = bytes[boneAnimationIndex + 1];
  284.                             }
  285.  
  286.                             if(numValid > k)
  287.                             {
  288.                                 animationValue = BitConverter.ToInt16(bytes, boneAnimationIndex + (k + 1) * 2);
  289.                             }
  290.                             else
  291.                             {
  292.                                 animationValue = BitConverter.ToInt16(bytes, boneAnimationIndex + numValid * 2);
  293.                             }
  294.  
  295.                             position[j] += animationValue * m_bones[b].scale[j];
  296.                         }
  297.                     }
  298.  
  299.                     // Rotation
  300.                     for(int j = 0; j < 3; j++)
  301.                     {
  302.                         if(animOffset[j + 3] == 0)
  303.                         {
  304.                             eulerRotation[j] = m_bones[b].value[j + 3];
  305.                         }
  306.                         else
  307.                         {
  308.  
  309.                             boneAnimationIndex  = animationOffsetIndex + animOffset[j + 3];
  310.                             numValid            = bytes[boneAnimationIndex];
  311.                             numTotal            = bytes[boneAnimationIndex + 1];
  312.                            
  313.                             k = f;
  314.                            
  315.                             while (numTotal <= k)
  316.                             {
  317.                                 k -= numTotal;
  318.                                 boneAnimationIndex += (numValid + 1) * 2;
  319.                                 numValid            = bytes[boneAnimationIndex];
  320.                                 numTotal            = bytes[boneAnimationIndex + 1];
  321.                             }
  322.  
  323.                             if(numValid > k)
  324.                             {
  325.                                 eulerRotation[j] = BitConverter.ToInt16(bytes, boneAnimationIndex + (k + 1) * 2);
  326.                             }
  327.                             else
  328.                             {
  329.                                 eulerRotation[j] = BitConverter.ToInt16(bytes, boneAnimationIndex + numValid * 2);
  330.                             }
  331.                         }
  332.  
  333.                         eulerRotation[j] = (m_bones[b].value[j + 3] + eulerRotation[j] * m_bones[b].scale[j + 3]);
  334.                     }
  335.  
  336.                     rotation            = AngleQuaternion(eulerRotation);
  337.                     frame               = f / fps;
  338.  
  339.                     xPositionKeys[f]    = new Keyframe(frame, position.x);
  340.                     yPositionKeys[f]    = new Keyframe(frame, position.y);
  341.                     zPositionKeys[f]    = new Keyframe(frame, position.z);
  342.                     xRotationKeys[f]    = new Keyframe(frame, rotation.x);
  343.                     yRotationKeys[f]    = new Keyframe(frame, rotation.y);
  344.                     zRotationKeys[f]    = new Keyframe(frame, rotation.z);
  345.                     wRotationKeys[f]    = new Keyframe(frame, rotation.w);
  346.                 }
  347.  
  348.                 path    = m_bones[b].path;
  349.  
  350.                 m_animations[s].SetCurve(path, typeof(Transform), "localPosition.x", new AnimationCurve(xPositionKeys));
  351.                 m_animations[s].SetCurve(path, typeof(Transform), "localPosition.y", new AnimationCurve(yPositionKeys));
  352.                 m_animations[s].SetCurve(path, typeof(Transform), "localPosition.z", new AnimationCurve(zPositionKeys));
  353.                 m_animations[s].SetCurve(path, typeof(Transform), "localRotation.x", new AnimationCurve(xRotationKeys));
  354.                 m_animations[s].SetCurve(path, typeof(Transform), "localRotation.y", new AnimationCurve(yRotationKeys));
  355.                 m_animations[s].SetCurve(path, typeof(Transform), "localRotation.z", new AnimationCurve(zRotationKeys));
  356.                 m_animations[s].SetCurve(path, typeof(Transform), "localRotation.w", new AnimationCurve(wRotationKeys));
  357.             }
  358.  
  359.             m_animations[s].EnsureQuaternionContinuity();
  360.             m_animations[s].wrapMode = WrapMode.Loop; // TEMP
  361.         }
  362.     }
  363.     private void        ReadControllers(byte[] modelBytes)
  364.     {
  365.         int             controllerCount, controllerIndex, boneId, type, rest, controllerId;
  366.         float           startValue, endValue;
  367.         AnimationCurve  curve;
  368.  
  369.         controllerCount     = BitConverter.ToInt32(modelBytes, 148);
  370.         controllerIndex     = BitConverter.ToInt32(modelBytes, 152);
  371.         m_boneControllers   = new AnimationClip[5];
  372.  
  373.         for(int i = 0; i < controllerCount; i++)
  374.         {
  375.             boneId          = BitConverter.ToInt32(modelBytes, controllerIndex + i * 24);
  376.             type            = BitConverter.ToInt32(modelBytes, controllerIndex + 4 + i * 24);
  377.             startValue      = BitConverter.ToSingle(modelBytes, controllerIndex + 8 + i * 24);
  378.             endValue        = BitConverter.ToSingle(modelBytes, controllerIndex + 12 + i * 24);
  379.             rest            = BitConverter.ToInt32(modelBytes, controllerIndex + 16 + i * 24);
  380.             controllerId    = BitConverter.ToInt32(modelBytes, controllerIndex + 20 + i * 24);
  381.  
  382.             if(m_boneControllers[controllerId] == null)
  383.             {
  384.                 m_boneControllers[controllerId] = new AnimationClip();
  385.             }
  386.  
  387.             curve = new AnimationCurve();
  388.             curve.AddKey(new Keyframe(0, startValue));
  389.             curve.AddKey(new Keyframe(1, endValue));
  390.  
  391.             m_boneControllers[controllerId].SetCurve(m_bones[boneId].path, typeof(Transform), "", curve);
  392.         }
  393.     }
  394.     private void        ReadMeshes(byte[] modelBytes, byte[] textureBytes)
  395.     {
  396.         int                 numBodyParts, numModels, numMeshes, numVertices, numIterations, numBones, numNormals,
  397.                             bodyPartsIndex, modelIndex, meshIndex, vertexIndex, vertexInfoIndex, normalIndex,
  398.                             triangleIndex, skinIndex, textureIndex, bufferIndex,
  399.                             textureWidth, textureHeight;
  400.         float               uCoord, vCoord;
  401.         bool                isTriangleFan, invertTriangle;
  402.         int[]               triangleBuffer;
  403.         string              textureName;
  404.         Vector3[]           normalArray;
  405.         List<Vector3>       vertices;
  406.         List<Vector3>       normals;
  407.         List<Vector2>       uvCoords;
  408.         List<BoneWeight>    weights;
  409.         List<int>[]         triangles;
  410.         List<bool>          usedVertex;
  411.         Vector3             vector3;
  412.         Vector2             vector2;
  413.         BoneWeight          boneWeight;
  414.         GameObject[]        tempObjects;
  415.         GameObject          rootObject;
  416.         Matrix4x4[]         bindPoses;
  417.  
  418.         numBones            = m_bones.Length;
  419.         textureIndex        = BitConverter.ToInt32(textureBytes, 184);
  420.         numBodyParts        = BitConverter.ToInt32(modelBytes, 204);
  421.         bodyPartsIndex      = BitConverter.ToInt32(modelBytes, 208);
  422.  
  423.         m_meshPartNames     = new string[numBodyParts];
  424.         m_meshes            = new Mesh[numBodyParts][];
  425.         m_meshMaterials     = new Material[numBodyParts][][];
  426.         vertices            = new List<Vector3>();
  427.         normals             = new List<Vector3>();
  428.         uvCoords            = new List<Vector2>();
  429.         weights             = new List<BoneWeight>();
  430.         usedVertex          = new List<bool>();
  431.  
  432.         bindPoses           = new Matrix4x4[numBones];
  433.         tempObjects         = new GameObject[numBones];
  434.         rootObject          = new GameObject();
  435.  
  436.         for(int i = 0; i < numBones; i++)
  437.         {
  438.             tempObjects[i] = new GameObject();
  439.  
  440.             if(m_bones[i].parent == -1)
  441.             {
  442.                 tempObjects[i].transform.parent = rootObject.transform;
  443.             }
  444.             else
  445.             {
  446.                 tempObjects[i].transform.parent = tempObjects[m_bones[i].parent].transform;
  447.             }
  448.  
  449.             bindPoses[i] = tempObjects[i].transform.worldToLocalMatrix * rootObject.transform.localToWorldMatrix;
  450.         }
  451.  
  452.         GameObject.DestroyImmediate(rootObject);
  453.         for(int i = 0; i < tempObjects.Length; i++)
  454.         {
  455.             GameObject.DestroyImmediate(tempObjects[i]);
  456.         }
  457.        
  458.         for(int p = 0; p < numBodyParts; p++)
  459.         {
  460.             m_meshPartNames[p]      = ByteArrayUtils.ReadASCIIString(modelBytes, bodyPartsIndex + p * 76, 64);
  461.             numModels               = BitConverter.ToInt32(modelBytes, bodyPartsIndex + 64 + p * 76);
  462.             modelIndex              = BitConverter.ToInt32(modelBytes, bodyPartsIndex + 72 + p * 76);
  463.  
  464.             m_meshes[p]             = new Mesh[numModels];
  465.             m_meshMaterials[p]      = new Material[numModels][];
  466.  
  467.             for(int m = 0; m < numModels; m++)
  468.             {
  469.                 m_meshes[p][m]      = new Mesh();
  470.                 m_meshes[p][m].name = ByteArrayUtils.ReadASCIIString(modelBytes, modelIndex + m * 112, 64);
  471.                
  472.                 numMeshes           = BitConverter.ToInt32(modelBytes, modelIndex + 72 + m * 112);
  473.                 meshIndex           = BitConverter.ToInt32(modelBytes, modelIndex + 76 + m * 112);
  474.                 numVertices         = BitConverter.ToInt32(modelBytes, modelIndex + 80 + m * 112);
  475.                 vertexInfoIndex     = BitConverter.ToInt32(modelBytes, modelIndex + 84 + m * 112);
  476.                 vertexIndex         = BitConverter.ToInt32(modelBytes, modelIndex + 88 + m * 112);
  477.                 numNormals          = BitConverter.ToInt32(modelBytes, modelIndex + 92 + m * 112);
  478.                 normalIndex         = BitConverter.ToInt32(modelBytes, modelIndex + 100 + m * 112);
  479.  
  480.                 vertices.Clear();
  481.                 normals.Clear();
  482.                 uvCoords.Clear();
  483.                 weights.Clear();
  484.                 usedVertex.Clear();
  485.  
  486.                 normalArray             = new Vector3[numNormals];
  487.                 triangles               = new List<int>[numMeshes];
  488.                 m_meshMaterials[p][m]   = new Material[numMeshes];
  489.  
  490.                 for(int i = 0; i < numVertices; i++)
  491.                 {
  492.                     vector3                 = ByteArrayUtils.ReadVector3(modelBytes, vertexIndex + i * 12);
  493.                     boneWeight              = new BoneWeight();
  494.                     boneWeight.boneIndex0   = modelBytes[vertexInfoIndex + i];
  495.                     boneWeight.weight0      = 1;
  496.  
  497.                     vertices.Add(vector3);
  498.                     weights.Add(boneWeight);
  499.                     uvCoords.Add(Vector2.zero);
  500.                     normals.Add(Vector3.one);
  501.                     usedVertex.Add(false);
  502.                 }
  503.  
  504.                 for(int i = 0; i < numNormals; i++)
  505.                 {
  506.                     normalArray[i]  = ByteArrayUtils.ReadVector3(modelBytes, normalIndex + i * 12);
  507.                 }
  508.  
  509.                 for(int i = 0; i < numMeshes; i++)
  510.                 {
  511.                     triangleIndex   = BitConverter.ToInt32(modelBytes, meshIndex + 4 + i * 20);
  512.                     skinIndex       = BitConverter.ToInt32(modelBytes, meshIndex + 8 + i * 20);
  513.                     textureName     = ByteArrayUtils.ReadASCIIString(textureBytes, textureIndex + skinIndex * 80, 64);
  514.                     textureWidth    = BitConverter.ToInt32(textureBytes, textureIndex + 68 + skinIndex * 80);
  515.                     textureHeight   = BitConverter.ToInt32(textureBytes, textureIndex + 72 + skinIndex * 80);
  516.  
  517.                     m_meshMaterials[p][m][i]    = GetMaterial(textureName);
  518.                     triangles[i]                = new List<int>();
  519.  
  520.                     while((numIterations = BitConverter.ToInt16(modelBytes, triangleIndex)) != 0)
  521.                     {
  522.                         triangleIndex += 2;
  523.  
  524.                         if(numIterations < 0)
  525.                         {
  526.                             isTriangleFan   = true;
  527.                             numIterations   = -numIterations;
  528.                         }
  529.                         else
  530.                         {
  531.                             isTriangleFan   = false;
  532.                         }
  533.  
  534.                         triangleBuffer  = new int[numIterations];
  535.  
  536.                         for(; numIterations > 0; numIterations--, triangleIndex += 8)
  537.                         {
  538.                             bufferIndex                 = triangleBuffer.Length - numIterations;
  539.                             triangleBuffer[bufferIndex] = BitConverter.ToInt16(modelBytes, triangleIndex);
  540.                             uCoord                      = BitConverter.ToInt16(modelBytes, triangleIndex + 4) / (float)textureWidth;
  541.                             vCoord                      = BitConverter.ToInt16(modelBytes, triangleIndex + 6) / (float)textureHeight;
  542.                             vector2                     = new Vector2(uCoord, vCoord);
  543.                             vector3                     = normalArray[BitConverter.ToInt16(modelBytes, triangleIndex + 2)];
  544.  
  545.                             if(!usedVertex[triangleBuffer[bufferIndex]])
  546.                             {
  547.                                 uvCoords[triangleBuffer[bufferIndex]]   = vector2;
  548.                                 normals[triangleBuffer[bufferIndex]]    = vector3;
  549.                                 usedVertex[triangleBuffer[bufferIndex]] = true;
  550.                             }
  551.                             else
  552.                             {
  553.                                 // TODO: Оптимизировать этот участок
  554.                                 if(uvCoords[triangleBuffer[bufferIndex]] != vector2 || normals[triangleBuffer[bufferIndex]] != vector3)
  555.                                 {
  556.                                     vertices.Add(vertices[triangleBuffer[bufferIndex]]);
  557.                                     normals.Add(normals[triangleBuffer[bufferIndex]]);
  558.                                     weights.Add(weights[triangleBuffer[bufferIndex]]);
  559.                                     uvCoords.Add(vector2);
  560.                                     usedVertex.Add(true);
  561.  
  562.                                     triangleBuffer[bufferIndex] = vertices.Count - 1;
  563.                                 }
  564.                             }
  565.                         }
  566.  
  567.                         if(isTriangleFan)
  568.                         {
  569.                             for(int j = 0; j < triangleBuffer.Length - 2; j++)
  570.                             {
  571.                                 triangles[i].Add(triangleBuffer[j + 2]);
  572.                                 triangles[i].Add(triangleBuffer[j + 1]);
  573.                                 triangles[i].Add(triangleBuffer[0]);
  574.                             }
  575.                         }
  576.                         else
  577.                         {
  578.                             invertTriangle = false;
  579.  
  580.                             for(int j = 0; j < triangleBuffer.Length - 2; j++)
  581.                             {
  582.                                 triangles[i].Add(triangleBuffer[j + (invertTriangle?1:2)]);
  583.                                 triangles[i].Add(triangleBuffer[j + (invertTriangle?2:1)]);
  584.                                 triangles[i].Add(triangleBuffer[j]);
  585.  
  586.                                 invertTriangle = !invertTriangle;
  587.                             }
  588.                         }
  589.                     }
  590.                 }
  591.  
  592.                 m_meshes[p][m].subMeshCount     = numMeshes;
  593.                 m_meshes[p][m].vertices         = vertices.ToArray();
  594.                 m_meshes[p][m].normals          = normals.ToArray();
  595.                 m_meshes[p][m].uv               = uvCoords.ToArray();
  596.                 m_meshes[p][m].boneWeights      = weights.ToArray();
  597.                 m_meshes[p][m].bindposes        = bindPoses;
  598.  
  599.                 for(int i = 0; i < triangles.Length; i++)
  600.                 {
  601.                     m_meshes[p][m].SetTriangles(triangles[i].ToArray(), i);
  602.                 }
  603.  
  604.                 m_meshes[p][m].RecalculateBounds();
  605.                 m_meshes[p][m].Optimize();
  606.             }
  607.         }
  608.     }
  609.     private void        ReadTextures(byte[] textureBytes)
  610.     {
  611.         Texture2D       texture;
  612.         int             pix1, pix2, pix3, pix4, outWidth, outHeight,palStartIndex, dataStartIndex,
  613.                         flags, textureWidth, textureHeight, textureIndex, numTextures;
  614.         int[]           row1, row2, col1, col2;
  615.         float           r, g, b;
  616.         Color[]         colors;
  617.         string          name;
  618.  
  619.         if(textureBytes != null)
  620.         {
  621.             numTextures     = BitConverter.ToInt32(textureBytes, 180);
  622.             textureIndex    = BitConverter.ToInt32(textureBytes, 184);
  623.  
  624.             if(textureIndex != 0)
  625.             {
  626.                 m_materials     = new Material[numTextures];
  627.                 m_textures      = new Texture[numTextures];
  628.  
  629.                 for(int t = 0; t < numTextures; t++)
  630.                 {
  631.                     name            = ByteArrayUtils.ReadASCIIString(textureBytes, textureIndex + t * 80, 64);
  632.                     flags           = BitConverter.ToInt32(textureBytes, textureIndex + 64 + t * 80);
  633.                     textureWidth    = BitConverter.ToInt32(textureBytes, textureIndex + 68 + t * 80);
  634.                     textureHeight   = BitConverter.ToInt32(textureBytes, textureIndex + 72 + t * 80);
  635.                     dataStartIndex  = BitConverter.ToInt32(textureBytes, textureIndex + 76 + t * 80);
  636.  
  637.                     for(outWidth = 1; outWidth < textureWidth; outWidth <<= 1);
  638.                     if (outWidth > 1024) outWidth = 1024;
  639.                     for (outHeight = 1; outHeight < textureHeight; outHeight <<= 1);
  640.                     if (outHeight > 1024) outHeight = 1024;
  641.  
  642.                     colors          = new Color[outWidth * outHeight];
  643.                     palStartIndex   = textureWidth * textureHeight + dataStartIndex;
  644.  
  645.                     col1    = new int[outWidth];
  646.                     col2    = new int[outWidth];
  647.  
  648.                     for (int i = 0; i < outWidth; i++)
  649.                     {
  650.                         col1[i] = (int)((i + 0.25f) * (textureWidth / (float)outWidth));
  651.                         col2[i] = (int)((i + 0.75f) * (textureWidth / (float)outWidth));
  652.                     }
  653.  
  654.                     row1    = new int[outHeight];
  655.                     row2    = new int[outHeight];
  656.  
  657.                     for (int i = 0; i < outHeight; i++)
  658.                     {
  659.                         row1[i] = (int)((i + 0.25f) * (textureHeight / (float)outHeight)) * textureWidth;
  660.                         row2[i] = (int)((i + 0.75f) * (textureHeight / (float)outHeight)) * textureWidth;
  661.                     }
  662.  
  663.                     for (int i = 0 ; i < outHeight ; i++)
  664.                     {
  665.                         for (int j = 0 ; j < outWidth ; j++)
  666.                         {
  667.                             pix1 = palStartIndex + textureBytes[dataStartIndex + row1[i] + col1[j]] * 3;
  668.                             pix2 = palStartIndex + textureBytes[dataStartIndex + row1[i] + col2[j]] * 3;
  669.                             pix3 = palStartIndex + textureBytes[dataStartIndex + row2[i] + col1[j]] * 3;
  670.                             pix4 = palStartIndex + textureBytes[dataStartIndex + row2[i] + col2[j]] * 3;
  671.  
  672.                             r = (float)((textureBytes[pix1    ] + textureBytes[pix2    ] + textureBytes[pix3    ] + textureBytes[pix4    ]) / 1020.0f);
  673.                             g = (float)((textureBytes[pix1 + 1] + textureBytes[pix2 + 1] + textureBytes[pix3 + 1] + textureBytes[pix4 + 1]) / 1020.0f);
  674.                             b = (float)((textureBytes[pix1 + 2] + textureBytes[pix2 + 2] + textureBytes[pix3 + 2] + textureBytes[pix4 + 2]) / 1020.0f);
  675.  
  676.                             colors[i * outWidth + j] = new Color(r,g,b,1);
  677.                         }
  678.                     }
  679.  
  680.                     texture = new Texture2D(outWidth, outHeight, TextureFormat.ARGB32, false);
  681.                     texture.SetPixels(colors);
  682.                     texture.Apply(false, true);
  683.  
  684.                     m_materials[t]              = new Material(Shader.Find("Diffuse"));
  685.                     m_materials[t].name         = name;
  686.                     m_materials[t].mainTexture  = texture;
  687.                     m_textures[t]               = texture;
  688.                 }
  689.             }
  690.         }
  691.     }
  692.  
  693.     private Material    GetMaterial(string name)
  694.     {
  695.         if(m_materials != null)
  696.         {
  697.             for(int i = 0; i < m_materials.Length; i++)
  698.             {
  699.                 if(m_materials[i].name == name)
  700.                 {
  701.                     return m_materials[i];
  702.                 }
  703.             }
  704.         }
  705.  
  706.         return null;
  707.     }
  708.     private Quaternion  AngleQuaternion(Vector3 vector)
  709.     {
  710.         float       angle;
  711.         float       sr, sp, sy, cr, cp, cy, crcp, srsp, srcp, crsp;
  712.  
  713.         angle   = vector[2] * 0.5f;
  714.         sy      = Mathf.Sin(angle);
  715.         cy      = Mathf.Cos(angle);
  716.         angle   = vector[1] * 0.5f;
  717.         sp      = Mathf.Sin(angle);
  718.         cp      = Mathf.Cos(angle);
  719.         angle   = vector[0] * 0.5f;
  720.         sr      = Mathf.Sin(angle);
  721.         cr      = Mathf.Cos(angle);
  722.  
  723.         crcp    = cr*cp;
  724.         srsp    = sr*sp;
  725.         srcp    = sr*cp;
  726.         crsp    = cr*sp;
  727.  
  728.         return new Quaternion(srcp*cy-crsp*sy, crsp*cy+srcp*sy, crcp*sy-srsp*cy, crcp*cy+srsp*sy);
  729.     }
  730. }
Advertisement
Add Comment
Please, Sign In to add comment