Esempio n. 1
0
        public void ReadRawFaces(int off)
        {
            RawFaces = new List <RawFace>();
            int size = BitConverter.ToInt32(memory, off);

            if (size != 8)
            {
                ReadUnknown5(off);
                return;
            }
            offFace = off;
            int     count = BitConverter.ToInt32(memory, off + 4);
            int     pos   = off + 8;
            RawFace f     = new RawFace();

            for (int i = 0; i < count; i++)
            {
                f.e0 = BitConverter.ToUInt16(memory, pos);
                f.e1 = BitConverter.ToUInt16(memory, pos + 2);
                f.e2 = BitConverter.ToUInt16(memory, pos + 4);
                RawFaces.Add(f);
                pos += size;
            }
            currpos = pos;
        }
Esempio n. 2
0
        public RealGeometryFile Collect(RawGeometryFile rawGeom)
        {
            RealGeometryFile geom   = new RealGeometryFile();
            Hashtable        MatTex = new Hashtable();

            LoadMaterialHT();

            for (int i = 0; i < rawGeom.Header.NumMaterials; i++)
            {
                MatTexStringPair pair = new MatTexStringPair();
                string           mat  = rawGeom.Header.MatNames[i].Data;
                if (materialHT.ContainsKey(mat))
                {
                    mat = (string)materialHT[mat];
                }
                string[] split = mat.Split('/');
                if (split.Length < 2)
                {
                    Compiler.WarningOutput(string.Format("Material {0} has invalid name.", mat));
                    pair.Material = "DEFAULT";
                    pair.Texture  = "DEFAULT";
                }
                else
                {
                    pair.Material = split[0];
                    pair.Texture  = split[1];
                }
                MatTex.Add(i, pair);
            }


            ArrayList mountPointObjects = new ArrayList();
            //ArrayList transparentObjects = new ArrayList(new string[] {"base_a","kit00_front_window_a","kit00_left_headlight_a"});
            ArrayList transparentObjects = new ArrayList();
            int       diffuse;

            ArrayList basePartObjects = new ArrayList();

            for (int i = 0; i < rawGeom.Header.NumObjects; i++)
            {
                Compiler.VerboseOutput(string.Format("Compiling object {0}: {1}", i + 1, rawGeom.Header.ObjHeaders[i].ObjName));

                if (rawGeom.Header.ObjHeaders[i].ObjName.Data.StartsWith("#"))
                {
                    string mountName;
                    uint   mountHash;
                    mountName = rawGeom.Header.ObjHeaders[i].ObjName.Data.Substring(1).ToUpper();
                    if (mountName.IndexOf("[") > -1)
                    {
                        mountName = mountName.Substring(0, mountName.IndexOf("["));
                    }
                    if (mountName.StartsWith("0x"))
                    {
                        mountHash = uint.Parse(mountName.Substring(2), NumberStyles.HexNumber);
                    }
                    else
                    {
                        mountHash = RealHash(mountName);
                    }
                    Compiler.VerboseOutput(string.Format(" + Mount Point Name: {0}", mountName));
                    Compiler.VerboseOutput(string.Format(" + Compiled Hash: 0x{0:x}", mountHash));
                    RealMountPoint mp = new RealMountPoint();
                    mp.Hash        = mountHash;
                    mp.Transform   = new RealMatrix();
                    mp.Transform.m = new float[16];
                    float[] transform = rawGeom.Header.ObjHeaders[i].Transform;
                    mp.Transform.m[0]  = 1.0f;
                    mp.Transform.m[5]  = 1.0f;
                    mp.Transform.m[10] = 1.0f;
                    mp.Transform.m[15] = 1.0f;
                    mp.Transform.m[12] = transform[14];                     //z
                    mp.Transform.m[13] = transform[12];                     //x
                    mp.Transform.m[14] = transform[13];                     //y

                    mountPointObjects.Add(mp);
                }
                else
                {
                    Hashtable  subMeshes = new Hashtable();
                    UniqueList textures  = new UniqueList();
                    UniqueList materials = new UniqueList();

                    if (transparentObjects.Contains(rawGeom.Header.ObjHeaders[i].ObjName.ToString()))
                    {
                        diffuse = 0x7FFFFFFF;
                    }
                    else
                    {
                        diffuse = -1;
                    }

                    for (int j = 0; j < rawGeom.Header.ObjHeaders[i].NumFaces; j++)
                    {
                        SubMesh          subMesh;
                        RawFace          face    = rawGeom.Objects[i].Faces[j];
                        MatTexPair       pair    = new MatTexPair();
                        MatTexStringPair strPair = (MatTexStringPair)MatTex[face.MatIndex];
                        pair.Material = materials.Add(strPair.Material);
                        pair.Texture  = textures.Add(strPair.Texture);

                        if (subMeshes.ContainsKey(pair))
                        {
                            subMesh = subMeshes[pair] as SubMesh;
                        }
                        else
                        {
                            subMesh            = new SubMesh();
                            subMesh.TextureId  = pair.Texture;
                            subMesh.MaterialId = pair.Material;
                            subMeshes.Add(pair, subMesh);
                        }

                        // note ZM default = CCW, MW = CW
                        RawVertex v1 = rawGeom.Objects[i].Vertices[face.I3];
                        RawVertex v2 = rawGeom.Objects[i].Vertices[face.I2];
                        RawVertex v3 = rawGeom.Objects[i].Vertices[face.I1];

                        RealVertex rv;

                        // v1
                        rv = new RealVertex();
                        rv.Initialize(true, 0);

                        /*
                         * rv.Position.x =-v1.X;
                         * rv.Position.y = v1.Z;
                         * rv.Position.z = v1.Y;
                         * rv.Normal.x =-v1.nX;
                         * rv.Normal.y = v1.nZ;
                         * rv.Normal.z = v1.nY;
                         */
                        rv.Position.x = v1.Z;
                        rv.Position.y = v1.X;
                        rv.Position.z = v1.Y;
                        rv.Normal.x   = v1.nZ;
                        rv.Normal.y   = v1.nX;
                        rv.Normal.z   = v1.nY;

                        rv.Diffuse = diffuse;
                        rv.UV.u    = face.tU3;
                        rv.UV.v    = face.tV3;

                        subMesh.IndexList.Add((ushort)subMesh.VertexList.Add(rv));

                        // v2
                        rv = new RealVertex();
                        rv.Initialize(true, 0);

                        /*
                         * rv.Position.x =-v2.X;
                         * rv.Position.y = v2.Z;
                         * rv.Position.z = v2.Y;
                         * rv.Normal.x =-v2.nX;
                         * rv.Normal.y = v2.nZ;
                         * rv.Normal.z = v2.nY;
                         */
                        rv.Position.x = v2.Z;
                        rv.Position.y = v2.X;
                        rv.Position.z = v2.Y;
                        rv.Normal.x   = v2.nZ;
                        rv.Normal.y   = v2.nX;
                        rv.Normal.z   = v2.nY;

                        rv.Diffuse = diffuse;
                        rv.UV.u    = face.tU2;
                        rv.UV.v    = face.tV2;

                        subMesh.IndexList.Add((ushort)subMesh.VertexList.Add(rv));

                        // v3
                        rv = new RealVertex();
                        rv.Initialize(true, 0);

                        /*
                         * rv.Position.x =-v3.X;
                         * rv.Position.y = v3.Z;
                         * rv.Position.z = v3.Y;
                         * rv.Normal.x =-v3.nX;
                         * rv.Normal.y = v3.nZ;
                         * rv.Normal.z = v3.nY;
                         */
                        rv.Position.x = v3.Z;
                        rv.Position.y = v3.X;
                        rv.Position.z = v3.Y;
                        rv.Normal.x   = v3.nZ;
                        rv.Normal.y   = v3.nX;
                        rv.Normal.z   = v3.nY;

                        rv.Diffuse = diffuse;
                        rv.UV.u    = face.tU1;
                        rv.UV.v    = face.tV1;

                        subMesh.IndexList.Add((ushort)subMesh.VertexList.Add(rv));
                    }

                    Compiler.VerboseOutput(string.Format(" + Compiled into {0} submeshes", subMeshes.Count));
                    SubMesh[] subMeshList = new SubMesh[subMeshes.Count];
                    subMeshes.Values.CopyTo(subMeshList, 0);
                    for (int j = 0; j < subMeshes.Count; j++)
                    {
                        SubMesh subMesh = subMeshList[j];

                        Compiler.VerboseOutput(string.Format(" + Submesh {0}:", j + 1));
                        Compiler.VerboseOutput(string.Format("    + Material:  {0}", materials[subMesh.MaterialId]));
                        Compiler.VerboseOutput(string.Format("    + Texture:   {0}", textures[subMesh.TextureId]));
                        Compiler.VerboseOutput(string.Format("    + Vertices:  {0}", subMesh.VertexList.Count));
                        Compiler.VerboseOutput(string.Format("    + Triangles: {0}", subMesh.IndexList.Count / 3));
                    }

                    Compiler.VerboseOutput(string.Format("Creating part data for binary object file..."));

                    RealGeometryPart part = new RealGeometryPart();

                    //----- part info ----------

                    RealVector4 boundsMin;
                    RealVector4 boundsMax;

                    if (rawGeom.Header.ObjHeaders[i].ObjName.Data.ToUpper().StartsWith("BASE_"))
                    {
                        basePartObjects.Add(part);
                    }

                    string resolvedName = ResolveRealNameForce(rawGeom.Header.ObjHeaders[i].ObjName.Data);

                    part.PartInfo.Hash        = RealHash(resolvedName);
                    part.PartInfo.PartName    = new FixedLenString(resolvedName);
                    part.PartInfo.ShaderCount = (byte)materials.Count;
                    part.PartInfo.Shaders     = new uint[materials.Count];
                    for (int j = 0; j < materials.Count; j++)
                    {
                        string matName = materials[j] as string;
                        if (matName.StartsWith("0x"))
                        {
                            part.PartInfo.Shaders[j] = uint.Parse(matName.Substring(2), NumberStyles.HexNumber);
                        }
                        else
                        {
                            part.PartInfo.Shaders[j] = RealHash(matName);
                        }
                    }

                    part.PartInfo.TextureCount = (byte)textures.Count;
                    part.PartInfo.Textures     = new uint[textures.Count];
                    for (int j = 0; j < textures.Count; j++)
                    {
                        string texName = textures[j] as string;
                        if (texName.StartsWith("0x"))
                        {
                            part.PartInfo.Textures[j] = uint.Parse(texName.Substring(2), NumberStyles.HexNumber);
                        }
                        else
                        {
                            part.PartInfo.Textures[j] = RealHash(ResolveRealName(texName));
                        }
                    }

                    part.PartInfo.Transform.m = rawGeom.Header.ObjHeaders[i].Transform;

                    /*
                     * part.PartInfo.Transform.m = new float[16];
                     * part.PartInfo.Transform.m[0] = 1.0f;
                     * part.PartInfo.Transform.m[5] = 1.0f;
                     * part.PartInfo.Transform.m[10] = 1.0f;
                     * part.PartInfo.Transform.m[15] = 1.0f;
                     */

                    part.PartInfo.TriangleCount = rawGeom.Header.ObjHeaders[i].NumFaces;

                    part.PartInfo.Unk1 = 0x00400018;
                    part.PartInfo.Unk2 = 0x000EA550;
                    part.PartInfo.Unk3 = 0x000EA550;

                    part.PartInfo.Unk4_MW = 0;
                    part.PartInfo.Unk5_MW = 1;
                    part.PartInfo.Unk6_MW = part.PartInfo.TriangleCount;

                    //----- part data ----------

                    part.PartData.Flags = 0x000080 + /* 0x000100 */ +0x004000 /* + 0x010000*/;

                    part.PartData.GroupCount = subMeshList.Length;
                    part.PartData.Groups     = new RealShadingGroup[subMeshList.Length];

                    int indexOffset = 0;
                    for (int j = 0; j < subMeshList.Length; j++)
                    {
                        SubMesh subMesh = subMeshList[j];
                        part.PartData.Groups[j] = new RealShadingGroup();

                        boundsMin = new RealVector4();
                        boundsMax = new RealVector4();
                        if (subMesh.VertexList.Count > 0)
                        {
                            RealVector3 v = ((RealVertex)subMesh.VertexList[0]).Position;
                            boundsMin.x = v.x;
                            boundsMin.y = v.y;
                            boundsMin.z = v.z;
                            boundsMax   = boundsMin;
                        }
                        for (int k = 1; k < subMesh.VertexList.Count; k++)
                        {
                            RealVector3 v = ((RealVertex)subMesh.VertexList[k]).Position;
                            if (v.x > boundsMax.x)
                            {
                                boundsMax.x = v.x;
                            }
                            if (v.y > boundsMax.y)
                            {
                                boundsMax.y = v.y;
                            }
                            if (v.z > boundsMax.z)
                            {
                                boundsMax.z = v.z;
                            }
                            if (v.x < boundsMin.x)
                            {
                                boundsMin.x = v.x;
                            }
                            if (v.y < boundsMin.y)
                            {
                                boundsMin.y = v.y;
                            }
                            if (v.z < boundsMin.z)
                            {
                                boundsMin.z = v.z;
                            }
                        }
                        part.PartData.Groups[j].BoundsMax = new RealVector3(boundsMax.x, boundsMax.y, boundsMax.z);
                        part.PartData.Groups[j].BoundsMin = new RealVector3(boundsMin.x, boundsMin.y, boundsMin.z);

                        part.PartData.Groups[j].Length        = subMesh.IndexList.Count;
                        part.PartData.Groups[j].TextureIndex0 = (byte)subMesh.TextureId;
                        part.PartData.Groups[j].TextureIndex1 = (byte)subMesh.TextureId;
                        part.PartData.Groups[j].TextureIndex2 = (byte)subMesh.TextureId;
                        part.PartData.Groups[j].TextureIndex3 = (byte)subMesh.TextureId;
                        part.PartData.Groups[j].TextureIndex4 = (byte)subMesh.TextureId;
                        part.PartData.Groups[j].ShaderIndex0  = (byte)subMesh.MaterialId;

                        part.PartData.Groups[j].Unk1  = 0x4;
                        part.PartData.Groups[j].Flags = part.PartData.Flags;

                        part.PartData.Groups[j].VertexCount   = subMesh.VertexList.Count;
                        part.PartData.Groups[j].TriangleCount = subMesh.IndexList.Count / 3;

                        part.PartData.Groups[j].Offset = indexOffset;

                        indexOffset += subMesh.IndexList.Count;
                    }

                    // -- bit of partinfo here -- caclulate bounds
                    boundsMin = new RealVector4();
                    boundsMax = new RealVector4();
                    if (part.PartData.Groups.Length > 0)
                    {
                        RealVector3 v = part.PartData.Groups[0].BoundsMin;
                        boundsMin.x = v.x;
                        boundsMin.y = v.y;
                        boundsMin.z = v.z;
                        v           = part.PartData.Groups[0].BoundsMax;
                        boundsMax.x = v.x;
                        boundsMax.y = v.y;
                        boundsMax.z = v.z;
                    }
                    for (int j = 1; j < part.PartData.Groups.Length; j++)
                    {
                        RealVector3 v = part.PartData.Groups[j].BoundsMax;
                        if (v.x > boundsMax.x)
                        {
                            boundsMax.x = v.x;
                        }
                        if (v.y > boundsMax.y)
                        {
                            boundsMax.y = v.y;
                        }
                        if (v.z > boundsMax.z)
                        {
                            boundsMax.z = v.z;
                        }

                        v = part.PartData.Groups[j].BoundsMin;
                        if (v.x < boundsMin.x)
                        {
                            boundsMin.x = v.x;
                        }
                        if (v.y < boundsMin.y)
                        {
                            boundsMin.y = v.y;
                        }
                        if (v.z < boundsMin.z)
                        {
                            boundsMin.z = v.z;
                        }
                    }
                    part.PartInfo.BoundMax = boundsMax;
                    part.PartInfo.BoundMin = boundsMin;

                    // -- end --


                    part.PartData.IndexCount = indexOffset;
                    part.PartData.Indices    = new ushort[indexOffset];

                    int vertexOffset = 0;
                    indexOffset = 0;
                    for (int j = 0; j < subMeshList.Length; j++)
                    {
                        for (int k = 0; k < subMeshList[j].IndexList.Count; k++)
                        {
                            part.PartData.Indices[indexOffset++] = (ushort)((ushort)subMeshList[j].IndexList[k] + vertexOffset);
                        }
                        vertexOffset += subMeshList[j].VertexList.Count;
                    }

                    part.PartData.TriangleCount = indexOffset / 3;
                    part.PartData.Unk1          = 0x12;
                    part.PartData.VBCount       = 1;
                    part.PartData.Vertices      = new RealVertex[vertexOffset];

                    vertexOffset = 0;
                    for (int j = 0; j < subMeshList.Length; j++)
                    {
                        for (int k = 0; k < subMeshList[j].VertexList.Count; k++)
                        {
                            part.PartData.Vertices[vertexOffset++] = (RealVertex)subMeshList[j].VertexList[k];
                        }
                    }

                    geom.AddPart(part);
                }

                Compiler.VerboseOutput(" + Complete.");
            }

            if (mountPointObjects.Count > 0)
            {
                Compiler.VerboseOutput("Merging mount points into base parts...");
                if (basePartObjects.Count == 0)
                {
                    Compiler.WarningOutput("Mount points provided without any base parts! Ignoring mount points.");
                }
                else
                {
                    RealMountPoint[] mountPoints = new RealMountPoint[mountPointObjects.Count];
                    mountPointObjects.CopyTo(mountPoints);
                    foreach (RealGeometryPart part in basePartObjects)
                    {
                        part.PartInfo.MountPoints = mountPoints;
                    }
                }
                Compiler.VerboseOutput(" + Complete.");
            }

            Compiler.VerboseOutput("Collecting part cross links...");
            LoadCrossLinks(geom);

            geom.GeometryInfo.PartCount   = geom.PartCount;
            geom.GeometryInfo.Unk1        = 0x1D;
            geom.GeometryInfo.Unk2        = 0x80;
            geom.GeometryInfo.ClassType   = new FixedLenString("DEFAULT", 0x20);
            geom.GeometryInfo.RelFilePath = new FixedLenString("GEOMETRY.BIN", 0x38);

            Compiler.VerboseOutput("Data successfully collected.");

            return(geom);
        }
Esempio n. 3
0
 public void ReadRawFaces(int off)
 {
     RawFaces = new List<RawFace>();
     int size = BitConverter.ToInt32(memory, off);
     if (size != 8)
     {
         ReadUnknown5(off);
         return;
     }
     offFace = off;
     int count = BitConverter.ToInt32(memory, off + 4);
     int pos = off + 8;
     RawFace f = new RawFace();
     for (int i = 0; i < count; i++)
     {
         f.e0 = BitConverter.ToUInt16(memory, pos);
         f.e1 = BitConverter.ToUInt16(memory, pos + 2);
         f.e2 = BitConverter.ToUInt16(memory, pos + 4);
         RawFaces.Add(f);
         pos += size;
     }
     currpos = pos;
 }
            public static Geometry LoadFromJson(Stream s)
            {
                Geometry geo = new Geometry();

                using (var reader = new StreamReader(s))
                {
                    var txt = reader.ReadToEnd();

                    var raw = JsonConvert.DeserializeObject <GeometryRaw>(txt);

                    RawVertex[] verts = new RawVertex[raw.vertexAttrEdge.Length];
                    RawEdge[]   edges = new RawEdge[raw.edgeAttrFace.Length];
                    RawFace[]   faces = new RawFace[raw.faceAttrEdge.Length];

                    geo.HasVertices = raw.vertexPositions != null;
                    geo.HasUVs      = raw.vertexUVs != null;
                    geo.HasNormals  = raw.vertexNormals != null;
                    geo.HasTangents = raw.vertexTangents != null;

                    if (geo.HasVertices)
                    {
                        for (int i = 0, j = 0; i < verts.Length; ++i)
                        {
                            verts[i].Position = new OpenTK.Vector3(raw.vertexPositions[j++], raw.vertexPositions[j++], raw.vertexPositions[j++]);
                        }
                    }
                    if (geo.HasUVs)
                    {
                        for (int i = 0, j = 0; i < verts.Length; ++i)
                        {
                            verts[i].UV = new OpenTK.Vector2(raw.vertexUVs[j++], raw.vertexUVs[j++]);
                        }
                    }
                    if (geo.HasNormals)
                    {
                        for (int i = 0, j = 0; i < verts.Length; ++i)
                        {
                            verts[i].Normal = new OpenTK.Vector3(raw.vertexNormals[j++], raw.vertexNormals[j++], raw.vertexNormals[j++]);
                        }
                    }
                    if (geo.HasTangents)
                    {
                        for (int i = 0, j = 0; i < verts.Length; ++i)
                        {
                            verts[i].Tangent = new OpenTK.Vector3(raw.vertexTangents[j++], raw.vertexTangents[j++], raw.vertexTangents[j++]);
                        }
                    }

                    for (int i = 0; i < verts.Length; ++i)
                    {
                        verts[i].Edge = raw.vertexAttrEdge[i];
                    }
                    for (int i = 0; i < edges.Length; ++i)
                    {
                        edges[i].Next     = raw.edgeAttrNext[i];
                        edges[i].Head     = raw.edgeAttrHead[i];
                        edges[i].Opposite = raw.edgeAttrOpposite[i];
                        edges[i].Face     = raw.edgeAttrFace[i];
                    }
                    for (int i = 0; i < faces.Length; ++i)
                    {
                        faces[i].Edge = raw.faceAttrEdge[i];
                    }

                    geo.vertices = verts.ToList();
                    geo.edges    = edges.ToList();
                    geo.faces    = faces.ToList();
                }

                geo.UpdateBoundingBox();
                geo.UpdateHasBoundary();

                return(geo);
            }