コード例 #1
0
            public LightNode(Stream mdlStream, Stream mdxStream, Type nodeType, AuroraModel model) : base(mdlStream, mdxStream, nodeType, model)
            {
                byte[] buffer = new byte[92];
                mdlStream.Read(buffer, 0, 92);

                flareRadius = BitConverter.ToSingle(buffer, 0);

                unknown = new uint[3];
                for (int i = 0; i < 3; i++)
                {
                    unknown[i] = BitConverter.ToUInt32(buffer, 4 + (i * 4));
                }

                flareSize        = new Vector3(BitConverter.ToSingle(buffer, 16), BitConverter.ToSingle(buffer, 20), BitConverter.ToSingle(buffer, 24));
                flarePos         = new Vector3(BitConverter.ToSingle(buffer, 28), BitConverter.ToSingle(buffer, 32), BitConverter.ToSingle(buffer, 36));
                flareColorShifts = new Vector3(BitConverter.ToSingle(buffer, 40), BitConverter.ToSingle(buffer, 44), BitConverter.ToSingle(buffer, 48));

                pointerArray = new byte[12];
                for (int i = 0; i < 12; i++)
                {
                    pointerArray[i] = buffer[52 + i];
                }

                priority          = BitConverter.ToUInt32(buffer, 64);
                ambientFlag       = BitConverter.ToUInt32(buffer, 68);
                dynamicFlag       = BitConverter.ToUInt32(buffer, 72);
                affectDynamicFlag = BitConverter.ToUInt32(buffer, 76);
                shadowFlag        = BitConverter.ToUInt32(buffer, 80);
                generateFlareFlag = BitConverter.ToUInt32(buffer, 84);
                fadingLightFlag   = BitConverter.ToUInt32(buffer, 88);
            }
コード例 #2
0
            public Node(Stream mdlStream, Stream mdxStream, Type nodeType, AuroraModel model)
            {
                byte[] buffer = new byte[78];
                mdlStream.Read(buffer, 0, 78);

                this.nodeType = nodeType;
                model.nodes.Add(this);

                superIndex = BitConverter.ToUInt16(buffer, 0);

                ushort nameIndex = BitConverter.ToUInt16(buffer, 2);

                name = (nameIndex < model.nodeNames.Length) ? model.nodeNames[nameIndex] : "";

                //get the node's position, flip the y and z co-ordinates to align with Unity axes
                position = new Vector3(BitConverter.ToSingle(buffer, 14), BitConverter.ToSingle(buffer, 22), BitConverter.ToSingle(buffer, 18));

                //get the node's orientation, and invert align with Unity axes
                Quaternion rot = new Quaternion(BitConverter.ToSingle(buffer, 30), BitConverter.ToSingle(buffer, 34), BitConverter.ToSingle(buffer, 38), BitConverter.ToSingle(buffer, 26));
                Quaternion inv = new Quaternion(-rot.x, -rot.z, -rot.y, rot.w);

                rotation = inv;

                uint childArrayOffset = BitConverter.ToUInt32(buffer, 42), childArrayCount = BitConverter.ToUInt32(buffer, 46), childArrayCapacity = BitConverter.ToUInt32(buffer, 50);
                uint curveKeyArrayOffset = BitConverter.ToUInt32(buffer, 54), curveKeyArrayCount = BitConverter.ToUInt32(buffer, 58), curveKeyArrayCapacity = BitConverter.ToUInt32(buffer, 62);
                uint curveDataArrayOffset = BitConverter.ToUInt32(buffer, 66), curveDataArrayCount = BitConverter.ToUInt32(buffer, 70), curveDataArrayCapacity = BitConverter.ToUInt32(buffer, 74);

                long pos = mdlStream.Position;

                //an array of offsets into the node list for each child of this node
                uint[] childArray = new uint[childArrayCount];

                mdlStream.Position = model.modelDataOffset + childArrayOffset;
                buffer             = new byte[4 * childArrayCount];
                mdlStream.Read(buffer, 0, 4 * (int)childArrayCount);

                for (int i = 0; i < childArrayCount; i++)
                {
                    childArray[i] = BitConverter.ToUInt32(buffer, 4 * i);
                }

                //curve data stores animated properties on the node
                curves = model.ReadAnimationCurves(mdlStream, curveKeyArrayCount, curveKeyArrayOffset, curveDataArrayCount, curveDataArrayOffset, this);

                children = new Node[childArrayCount];
                for (int i = 0; i < childArrayCount; i++)
                {
                    mdlStream.Position = model.modelDataOffset + childArray[i];
                    children[i]        = model.CreateNode(mdlStream, mdxStream, this);
                }

                mdlStream.Position = pos;
            }
コード例 #3
0
            public SaberNode(Stream mdlStream, Stream mdxStream, Type nodeType, AuroraModel model) : base(mdlStream, mdxStream, nodeType, model)
            {
                byte[] buffer = new byte[12];
                mdlStream.Read(buffer, 0, 12);

                uint offsetVertsCoords2 = BitConverter.ToUInt32(buffer, 0);
                uint offsetTexCoords    = BitConverter.ToUInt32(buffer, 4);
                uint offsetSaberData    = BitConverter.ToUInt32(buffer, 8);

                mdlStream.Position = model.modelDataOffset + vertexCoordsOffset;

                buffer = new byte[Vertices.Length * 12];
                mdlStream.Read(buffer, 0, buffer.Length);

                for (int i = 0; i < Vertices.Length; i++)
                {
                    Vertices[i] = new Vector3(BitConverter.ToSingle(buffer, 0), BitConverter.ToSingle(buffer, 8), BitConverter.ToSingle(buffer, 4));
                }
            }
コード例 #4
0
            public SkinnedMeshNode(Stream mdlStream, Stream mdxStream, Type nodeType, AuroraModel model) : base(mdlStream, mdxStream, nodeType, model)
            {
                byte[] buffer = new byte[102];
                mdlStream.Read(buffer, 0, 102);

                uint weightsOffset   = BitConverter.ToUInt32(buffer, 0);
                uint weightsCount    = BitConverter.ToUInt32(buffer, 4);
                uint weightsCapacity = BitConverter.ToUInt32(buffer, 8);

                uint mdxVertexStructOffsetBoneWeights   = BitConverter.ToUInt32(buffer, 12);
                uint mdxVertexStructOffsetBoneMappingID = BitConverter.ToUInt32(buffer, 16);

                uint boneMappingOffset = BitConverter.ToUInt32(buffer, 20);
                uint boneMappingCount  = BitConverter.ToUInt32(buffer, 24);

                uint boneQuatsOffset   = BitConverter.ToUInt32(buffer, 28);
                uint boneQuatsCount    = BitConverter.ToUInt32(buffer, 32);
                uint boneQuatsCapacity = BitConverter.ToUInt32(buffer, 36);

                uint boneVertsOffset   = BitConverter.ToUInt32(buffer, 40);
                uint boneVertsCount    = BitConverter.ToUInt32(buffer, 44);
                uint boneVertsCapacity = BitConverter.ToUInt32(buffer, 48);

                uint boneConstsOffset   = BitConverter.ToUInt32(buffer, 52);
                uint boneConstsCount    = BitConverter.ToUInt32(buffer, 56);
                uint boneConstsCapacity = BitConverter.ToUInt32(buffer, 60);

                boneToNodeMap = new short[16];
                for (int i = 0; i < boneToNodeMap.Length; i++)
                {
                    boneToNodeMap[i] = BitConverter.ToInt16(buffer, 64 + (i * 2));
                }

                //int spare = BitConverter.ToInt32(buffer, 98);

                // read the bone weights for each vertex
                mdxStream.Position = mdxNodeDataOffset + mdxVertexStructOffsetBoneWeights;

                buffer = new byte[mdxDataSize * Vertices.Length];
                mdxStream.Read(buffer, 0, (int)mdxDataSize * Vertices.Length);

                Weights = new BoneWeight[Vertices.Length];
                for (int i = 0, offset = 0; i < Vertices.Length; i++, offset += (int)mdxDataSize)
                {
                    Weights[i] = new BoneWeight {
                        weight0    = BitConverter.ToSingle(buffer, offset + 0),
                        weight1    = BitConverter.ToSingle(buffer, offset + 4),
                        weight2    = BitConverter.ToSingle(buffer, offset + 8),
                        weight3    = BitConverter.ToSingle(buffer, offset + 12),
                        boneIndex0 = (int)BitConverter.ToSingle(buffer, offset + 16),
                        boneIndex1 = (int)BitConverter.ToSingle(buffer, offset + 20),
                        boneIndex2 = (int)BitConverter.ToSingle(buffer, offset + 24),
                        boneIndex3 = (int)BitConverter.ToSingle(buffer, offset + 28),
                    };
                }

                // node to bone index maps each index in the node list to an index in this skin's bone list, or -1
                mdlStream.Position = model.modelDataOffset + boneMappingOffset;

                buffer = new byte[boneMappingCount * 4];
                mdlStream.Read(buffer, 0, (int)boneMappingCount * 4);

                nodeToBoneMap = new float[boneMappingCount];
                for (int j = 0; j < boneMappingCount; j++)
                {
                    nodeToBoneMap[j] = BitConverter.ToSingle(buffer, j * 4);
                }

                // read the bone quaternions
                mdlStream.Position = model.modelDataOffset + boneQuatsOffset;

                buffer = new byte[boneQuatsCount * 16];
                mdlStream.Read(buffer, 0, (int)boneQuatsCount * 16);

                Quaternion[] boneQuats = new Quaternion[boneQuatsCount];
                for (int j = 0, offset = 0; j < boneQuatsCount; j++, offset += 16)
                {
                    boneQuats[j] = new Quaternion(BitConverter.ToSingle(buffer, offset + 4), BitConverter.ToSingle(buffer, offset + 8), BitConverter.ToSingle(buffer, offset + 12), BitConverter.ToSingle(buffer, offset + 0));
                    boneQuats[j].Normalize();
                }

                // read the bone vertices
                mdlStream.Position = model.modelDataOffset + boneVertsOffset;

                buffer = new byte[boneVertsCount * 12];
                mdlStream.Read(buffer, 0, (int)boneVertsCount * 12);

                Vector3[] boneVerts = new Vector3[boneVertsCount];
                for (int j = 0, offset = 0; j < boneQuatsCount; j++, offset += 12)
                {
                    boneVerts[j] = new Vector3(BitConverter.ToSingle(buffer, offset + 0), BitConverter.ToSingle(buffer, offset + 8), BitConverter.ToSingle(buffer, offset + 4));
                }

                // read the bone consts
                mdlStream.Position = model.modelDataOffset + boneConstsOffset;

                buffer = new byte[boneConstsCount * 12];
                mdlStream.Read(buffer, 0, (int)boneConstsCount * 12);

                ushort[] boneConsts = new ushort[boneConstsCount];
                for (int j = 0; j < boneConstsCount; j++)
                {
                    boneConsts[j] = BitConverter.ToUInt16(buffer, j * 2);
                }
            }
コード例 #5
0
        public static GameObject LoadModel(string resref)
        {
            Stream mdl = GetStream(resref, ResourceType.MDL), mdx = GetStream(resref, ResourceType.MDX);

            if (mdl == null || mdx == null)
            {
                Debug.Log("Missing model: " + resref);
                return(new GameObject(resref));
            }

            AuroraModel auroraModel = new AuroraModel(mdl, mdx, targetGame);

            GameObject CreateObject(AuroraModel.Node node, Transform parent)
            {
                GameObject go = new GameObject(node.name);

                if (parent)
                {
                    go.transform.SetParent(parent, false);
                }

                go.transform.localPosition = node.position;
                go.transform.localRotation = node.rotation;

                if (node is AuroraModel.MeshNode)
                {
                    AuroraModel.MeshNode auroraMesh = (AuroraModel.MeshNode)node;
                    Mesh mesh = auroraMesh.CreateUnityMesh();

                    //if (auroraMesh.isWalkmesh) {
                    MeshCollider col = go.AddComponent <MeshCollider>();
                    col.cookingOptions = MeshColliderCookingOptions.None;
                    col.sharedMesh     = mesh;
                    //}

                    if (node is AuroraModel.SkinnedMeshNode)
                    {
                        SkinnedMeshRenderer renderer = go.AddComponent <SkinnedMeshRenderer>();

                        renderer.material   = LoadMaterial(auroraMesh.DiffuseMap, auroraMesh.LightMap);
                        renderer.sharedMesh = mesh;
                    }
                    else
                    {
                        go.AddComponent <MeshFilter>().mesh = mesh;

                        MeshRenderer renderer = go.AddComponent <MeshRenderer>();
                        renderer.material = LoadMaterial(auroraMesh.DiffuseMap, auroraMesh.LightMap);

                        //meshes with a null texture should be invisible
                        if (auroraMesh.DiffuseMap == "NULL")
                        {
                            renderer.enabled = false;
                        }
                    }
                }

                for (int i = 0; i < node.children.Length; i++)
                {
                    CreateObject(node.children[i], go.transform);
                }

                node.transform = go.transform;
                return(go);
            }

            GameObject model        = CreateObject(auroraModel.rootNode, null);

            void SkinObject(AuroraModel.Node node)
            {
                if (node is AuroraModel.SkinnedMeshNode)
                {
                    SkinnedMeshRenderer renderer = node.transform.GetComponent <SkinnedMeshRenderer>();
                    Mesh mesh = renderer.sharedMesh;

                    short[] boneMapping = ((AuroraModel.SkinnedMeshNode)node).boneToNodeMap;

                    List <Transform> boneTransforms = new List <Transform>();
                    List <Matrix4x4> bindPoses      = new List <Matrix4x4>();

                    for (int i = 0; i < boneMapping.Length; i++)
                    {
                        if (boneMapping[i] >= 0 && boneMapping[i] < auroraModel.nodes.Count)
                        {
                            Transform t = auroraModel.nodes[boneMapping[i]].transform;

                            boneTransforms.Add(t);
                            bindPoses.Add(t.worldToLocalMatrix * node.transform.localToWorldMatrix);
                        }
                    }

                    renderer.bones = boneTransforms.ToArray();
                    mesh.bindposes = bindPoses.ToArray();
                }

                for (int i = 0; i < node.children.Length; i++)
                {
                    SkinObject(node.children[i]);
                }
            }

            Animation animComponent = model.AddComponent <Animation>();

            AnimationClip[] clips = auroraModel.GetUnityAnimationClips();

            //TODO: check if animation is looping

            for (int i = 0; i < clips.Length; i++)
            {
                animComponent.AddClip(clips[i], clips[i].name);
            }

            SkinObject(auroraModel.rootNode);

            return(model);
        }
コード例 #6
0
            public MeshNode(Stream mdlStream, Stream mdxStream, Type nodeType, AuroraModel model) : base(mdlStream, mdxStream, nodeType, model)
            {
                //TODO: need to properly read walkmesh data
                if ((nodeType & Node.Type.AABB) == Node.Type.AABB)
                {
                    isWalkmesh = true;
                }

                byte[] buffer = new byte[88];
                mdlStream.Read(buffer, 0, 88);

                uint facesOffset   = BitConverter.ToUInt32(buffer, 8);
                uint facesCount    = BitConverter.ToUInt32(buffer, 12);
                uint facesCapacity = BitConverter.ToUInt32(buffer, 16);

                Vector3 minBounds = new Vector3(BitConverter.ToSingle(buffer, 20), BitConverter.ToSingle(buffer, 24), BitConverter.ToSingle(buffer, 28));
                Vector3 maxBounds = new Vector3(BitConverter.ToSingle(buffer, 32), BitConverter.ToSingle(buffer, 36), BitConverter.ToSingle(buffer, 40));

                radius           = BitConverter.ToSingle(buffer, 44);
                pointsAverage    = new Vector3(BitConverter.ToSingle(buffer, 48), BitConverter.ToSingle(buffer, 52), BitConverter.ToSingle(buffer, 56));
                diffuse          = new Color(BitConverter.ToSingle(buffer, 60), BitConverter.ToSingle(buffer, 64), BitConverter.ToSingle(buffer, 68));
                ambient          = new Color(BitConverter.ToSingle(buffer, 72), BitConverter.ToSingle(buffer, 76), BitConverter.ToSingle(buffer, 80));
                transparencyHint = BitConverter.ToUInt32(buffer, 84);

                buffer = new byte[88];
                mdlStream.Read(buffer, 0, 88);

                DiffuseMap = Encoding.UTF8.GetString(buffer, 0, 32).Split('\0')[0];
                LightMap   = Encoding.UTF8.GetString(buffer, 32, 32).Split('\0')[0];
                texMap3    = Encoding.UTF8.GetString(buffer, 64, 12).Split('\0')[0];
                texMap4    = Encoding.UTF8.GetString(buffer, 76, 12).Split('\0')[0];

                buffer = new byte[132];
                mdlStream.Read(buffer, 0, 132);

                uint indexArrayOffset   = BitConverter.ToUInt32(buffer, 0);
                uint indexArrayCount    = BitConverter.ToUInt32(buffer, 4);
                uint indexArrayCapacity = BitConverter.ToUInt32(buffer, 8);

                //the face data array contains a list of offsets to arrays which contain face data for this mesh, should never be more than one
                uint faceDataOffsetsOffset   = BitConverter.ToUInt32(buffer, 12);
                uint faceDataOffsetsCount    = BitConverter.ToUInt32(buffer, 16);
                uint faceDataOffsetsCapacity = BitConverter.ToUInt32(buffer, 20);

                //warn if there's more than one list of face data
                if (faceDataOffsetsCount > 1)
                {
                    Debug.LogWarning("faceDataOffsetsCount > 1, this mesh seems to have multiple face arrays.");
                }

                //regardless, we'll go to the start of the face data array and select the first offset, assuming that the first offset in the array points to the face data we want
                uint[] faceDataOffsets = new uint[faceDataOffsetsCount];

                long pos = mdlStream.Position;

                mdlStream.Position = model.modelDataOffset + faceDataOffsetsOffset;
                mdlStream.Read(buffer, 0, 4 * (int)faceDataOffsetsCount);
                mdlStream.Position = pos;

                for (int i = 0; i < faceDataOffsetsCount; i++)
                {
                    faceDataOffsets[i] = BitConverter.ToUInt32(buffer, i * 4);
                }

                saberBytes = new byte[] { buffer[48], buffer[49], buffer[50], buffer[51], buffer[52], buffer[53], buffer[54], buffer[55] };

                nAnimateUV     = BitConverter.ToUInt32(buffer, 56);
                fUVDirX        = BitConverter.ToSingle(buffer, 60);
                fUVDirY        = BitConverter.ToSingle(buffer, 64);
                fUVJitter      = BitConverter.ToSingle(buffer, 68);
                fUVJitterSpeed = BitConverter.ToSingle(buffer, 72);

                mdxDataSize   = BitConverter.ToUInt32(buffer, 76);
                mdxDataBitmap = BitConverter.ToUInt32(buffer, 80);

                uint mdxVertexVertexOffset  = BitConverter.ToUInt32(buffer, 84);
                uint mdxVertexNormalsOffset = BitConverter.ToUInt32(buffer, 88);
                uint mdxVertexNormalsUnused = BitConverter.ToUInt32(buffer, 92);

                int[] uvOffsets = new int[] {
                    BitConverter.ToInt32(buffer, 96),
                    BitConverter.ToInt32(buffer, 100),
                    BitConverter.ToInt32(buffer, 104),
                    BitConverter.ToInt32(buffer, 108),
                };

                int[] offsetToMdxTangent = new int[] {
                    BitConverter.ToInt32(buffer, 112),
                    BitConverter.ToInt32(buffer, 116),
                    BitConverter.ToInt32(buffer, 120),
                    BitConverter.ToInt32(buffer, 124),
                };

                ushort vertexCount  = BitConverter.ToUInt16(buffer, 128);
                ushort textureCount = BitConverter.ToUInt16(buffer, 130);

                int hasLightmap    = mdlStream.ReadByte();
                int rotateTex      = mdlStream.ReadByte();
                int backgroundGeom = mdlStream.ReadByte();
                int flagShadow     = mdlStream.ReadByte();
                int beaming        = mdlStream.ReadByte();
                int flagRender     = mdlStream.ReadByte();

                if (model.importFrom == Game.TSL)
                {
                    int dirtEnabled = mdlStream.ReadByte();
                    int tslPadding1 = mdlStream.ReadByte();

                    mdlStream.Read(buffer, 0, 4);
                    ushort dirtTex        = BitConverter.ToUInt16(buffer, 0);
                    ushort dirtCoordSpace = BitConverter.ToUInt16(buffer, 2);

                    int hideInHolograms = mdlStream.ReadByte();
                    int tslPadding2     = mdlStream.ReadByte();
                }

                buffer = new byte[18];
                mdlStream.Read(buffer, 0, 18);

                float totalArea = BitConverter.ToSingle(buffer, 2);

                mdxNodeDataOffset  = BitConverter.ToUInt32(buffer, 10);
                vertexCoordsOffset = BitConverter.ToUInt32(buffer, 14);

                Triangles = new int[facesCount * 3];                   //3 vertices per face
                Vertices  = new Vector3[vertexCount];
                Normals   = new Vector3[vertexCount];

                Vector2[][] uvs = new Vector2[4][];
                for (int t = 0; t < textureCount; t++)
                {
                    uvs[t] = new Vector2[vertexCount];
                }

                if (faceDataOffsetsCount == 0 || vertexCount == 0 || facesCount == 0)
                {
                    return;
                }

                long endPos = mdlStream.Position;

                buffer             = new byte[mdxDataSize * vertexCount];
                mdxStream.Position = mdxNodeDataOffset;
                mdxStream.Read(buffer, 0, (int)mdxDataSize * vertexCount);

                for (int i = 0, offset = 0; i < vertexCount; i++, offset += (int)mdxDataSize)
                {
                    //flip the y and z co-ordinates
                    Vertices[i] = new Vector3(BitConverter.ToSingle(buffer, offset + 0), BitConverter.ToSingle(buffer, offset + 8), BitConverter.ToSingle(buffer, offset + 4));
                    Normals[i]  = new Vector3(BitConverter.ToSingle(buffer, offset + 12), BitConverter.ToSingle(buffer, offset + 20), BitConverter.ToSingle(buffer, offset + 16)) * -1;

                    //read the uvs for each of the four (potential) texture maps,
                    for (int t = 0, uvOffset = 24; t < textureCount; t++, uvOffset += 8)
                    {
                        uvs[t][i] = new Vector2(BitConverter.ToSingle(buffer, offset + uvOffset + 0), BitConverter.ToSingle(buffer, offset + uvOffset + 4));
                    }
                }

                buffer             = new byte[6 * facesCount];      //6 bytes (3 shorts) per face
                mdlStream.Position = model.modelDataOffset + faceDataOffsets[0];
                mdlStream.Read(buffer, 0, 6 * (int)facesCount);

                if (textureCount != 0)
                {
                    for (int i = 0; i < facesCount; i++)
                    {
                        //flip faces 1 and 2 to keep the normals pointing out
                        Triangles[(i * 3) + 0] = BitConverter.ToUInt16(buffer, (i * 6) + 0);
                        Triangles[(i * 3) + 1] = BitConverter.ToUInt16(buffer, (i * 6) + 4);
                        Triangles[(i * 3) + 2] = BitConverter.ToUInt16(buffer, (i * 6) + 2);
                    }
                }

                if (uvs[0] != null)
                {
                    DiffuseUVs = uvs[0];
                }
                if (uvs[1] != null)
                {
                    LightmapUVs = uvs[1];
                }

                mdlStream.Position = endPos;
            }