예제 #1
0
 void ua_mdl_store_vertex(Vector3 vertex, int vertno, ref UWModel mod)
 {
     if (vertno >= mod.verts.Capacity)
     {
         mod.verts.Capacity = vertno + 1;
     }
     mod.verts[vertno] = vertex;
     if (mod.NoOfVerts < vertno)
     {
         mod.NoOfVerts = vertno;
     }
     writer.WriteLine("\tStoring Vertex " + vertno + " at " + vertex);
 }
예제 #2
0
    /* void convertVertToTris(int[] vertices,ref UWModel mod)
     * {
     *  switch (vertices.GetUpperBound(0))
     * {
     *   case 2:
     *     mod.tris.Add(vertices[2]);
     *     mod.tris.Add(vertices[1]);
     *     mod.tris.Add(vertices[0]);
     *     break;
     *   case 3://square
     *     mod.tris.Add(vertices[2]);
     *     mod.tris.Add(vertices[1]);
     *     mod.tris.Add(vertices[0]);
     *     mod.tris.Add(vertices[2]);
     *     mod.tris.Add(vertices[0]);
     *     mod.tris.Add(vertices[3]);
     *     break;
     *   default:
     *     {
     *       Debug.Log("What do I do here!! " + vertices.GetUpperBound(0));
     *       break;
     *     }
     * }
     * }*/

    /*  void convertVertToTris(int[] vertices, ref UWModel mod)
     * {
     * Vector2[] vertices2D =  new Vector2[vertices.GetUpperBound(0)+1];
     * for (int i=0; i<=vertices2D.GetUpperBound(0);i++)
     * {
     *   float u = mod.verts[vertices[i]].x/ mod.verts[vertices[i]].z;
     *   float v = mod.verts[vertices[i]].y/ mod.verts[vertices[i]].z;
     *   vertices2D[vertices2D.GetUpperBound(0)-i] = new Vector2(u,v);//mod.verts[vertices[i]];
     * }
     * Triangulator tr = new Triangulator(vertices2D);
     * int[] indices = tr.Triangulate();
     *
     * for (int i=0; i<=indices.GetUpperBound(0);i++)
     * {
     *   //find the original vertex ref and add it to the tri's
     *   for (int j=0; j<=mod.verts.Count;j++)
     *   {
     *
     *     if (mod.verts[j]==mod.verts[vertices[indices[i]]])
     *     {
     *       mod.tris.Add(j);
     *       break;
     *     }
     *   }
     * }
     *
     * }*/

    void convertVertToTris(int[] vertices, ref UWModel mod)
    {//This is sort of wrong.
        int startvert = 0;
        int lastvert  = 1;
        int NoOfVerts = vertices.GetUpperBound(0);

        string output = "\t";

        for (int i = 0; i <= vertices.GetUpperBound(0) - 2; i++)
        {
            mod.tris.Add(vertices[lastvert + 1]);
            mod.tris.Add(vertices[lastvert]);
            mod.tris.Add(vertices[startvert]);
            output   = output + "(" + (vertices[lastvert + 1]) + "," + vertices[lastvert] + "," + vertices[startvert] + ")";
            lastvert = lastvert + 1;
        }
        writer.Write(output + "\n");
    }
예제 #3
0
    void RenderModel(UWModel mod)
    {
        outputname = mod.modelname;
        verts      = new Vector3[mod.NoOfVerts + 1];
        for (int i = 0; i <= verts.GetUpperBound(0); i++)
        {
            verts[i] = mod.verts[i];
        }

        trisToRender = new int[mod.tris.Count];
        for (int i = 0; i <= trisToRender.GetUpperBound(0); i++)
        {
            if (mod.tris.Count > i)
            {
                trisToRender[i] = mod.tris[i];
            }
        }
    }
예제 #4
0
    //Ported from underworld adventures
    void ua_model_parse_node(char[] modelfile, long addressptr, ref UWModel mod, bool dump)
    {
        // parse node until end node
        bool loop  = true;
        int  instr = -1;

        while (loop)
        {
            // read next command
            int cmd = (int)(DataLoader.getValAtAddress(modelfile, addressptr, 16)); addressptr += 2;
            instr++;
            switch ((nodecmd)cmd)
            {
            // misc. nodes
            case nodecmd.M3_UW_ENDNODE: // 0000 end node
            {
                // ua_mdl_trace("[end]");
                writer.WriteLine("instr " + instr + "end");
                loop = false;
                break;
            }

            case nodecmd.M3_UW_ORIGIN: // 0078 define model center
            {
                writer.WriteLine("\nInstr " + instr + " origin");
                int vertno = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2; //ua_mdl_read_vertno(fd);
                mod.origin = mod.verts[vertno];                                          // mod.verts[vertno] ;

                float vx = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;    //ua_mdl_read_fixed(fd);
                float vy = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;    //ua_mdl_read_fixed(fd);
                float vz = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;    //ua_mdl_read_fixed(fd);

                writer.WriteLine("\tOrigin at " + mod.origin);

                int unk1 = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; //fread16(fd);
                // ua_mdl_trace("[origin] vertno=%u unk1=%04x origin=(%f,%f,%f)",
                //  vertno,unk1,vx,vy,vz);
                break;
            }


            // vertex definition nodes
            case nodecmd.M3_UW_VERTEX: // 007a define initial vertex
            {
                writer.WriteLine("\nInstr " + instr + " M3_UW_VERTEX");
                float vx     = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;  //ua_mdl_read_fixed(fd);
                float vy     = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;  //ua_mdl_read_fixed(fd);
                float vz     = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;  //ua_mdl_read_fixed(fd);
                int   vertno = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2; //ua_mdl_read_vertno(fd);

                Vector3 refvect = new Vector3((float)vx, (float)vy, (float)vz);
                ua_mdl_store_vertex(refvect, vertno, ref mod);
                //Debug.Log("\nInstr " + instr + "Vertex #" + vertno + "="  + refvect);
                // ua_mdl_trace("[vertex] vertno=%u vertex=(%f,%f,%f)",
                // vertno,vx,vy,vz);
                break;
            }


            case nodecmd.M3_UW_VERTICES: // 0082 define initial vertices
            {
                writer.WriteLine("\nInstr " + instr + " M3_UW_VERTICES");
                int nvert  = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; // fread16(fd);
                int vertno = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; // fread16(fd);
                for (int n = 0; n < nvert; n++)
                {
                    float vx = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2; //ua_mdl_read_fixed(fd);
                    float vy = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2; //ua_mdl_read_fixed(fd);
                    float vz = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2; //ua_mdl_read_fixed(fd);

                    Vector3 refvect = new Vector3((float)vx, (float)vy, (float)vz);
                    ua_mdl_store_vertex(refvect, vertno + n, ref mod);
                    //Debug.Log("\nInstr " + instr + "Vertex #" + vertno + "="  + refvect);
                    //ua_mdl_trace("%s[vertex] vertno=%u vertex=(%f,%f,%f)",
                    // n==0 ? "" : "\n      ",vertno+n,vx,vy,vz);
                }
            }
            break;

            case nodecmd.M3_UW_VERTEX_X: // 0086 define vertex offset X
            {
                writer.WriteLine("\nInstr " + instr + " offsetX");
                int   refvert = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;
                float vx      = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;//ua_mdl_read_fixed(fd);
                int   vertno  = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;

                Vector3 refvect = mod.verts[refvert];
                //  refvect.x += vx;
                //refvect  = new Vector3(refvect.x+(float)vx,refvect.y,refvect.z);
                Vector3 adj = new Vector3(vx, 0f, 0f);
                ua_mdl_store_vertex(refvect + adj, vertno, ref mod);
                //// Debug.Log("Vertex offsetX #" +(vertno) + "="  + (refvect+adj) + " from " + refvect + "(" + refvert + ")" + " adj = " +adj);
                //ua_mdl_trace("[vertex] vertno=%u vertex=(%f,%f,%f) x from=%u",
                //  vertno,refvect.x,refvect.y,refvect.z,refvert);
                break;
            }

            case nodecmd.M3_UW_VERTEX_Z: // 0088 define vertex offset Z
            {
                writer.WriteLine("\nInstr " + instr + " offsetZ");
                int   refvert = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;
                float vz      = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;//ua_mdl_read_fixed(fd);
                int   vertno  = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;

                Vector3 refvect = mod.verts[refvert];
                Vector3 adj     = new Vector3(0f, 0f, vz);
                ua_mdl_store_vertex(refvect + adj, vertno, ref mod);
                // Debug.Log("Vertex offsetZ #" +(vertno) + "="  + (refvect+adj) + " from " + refvect + "(" + refvert + ")" + " adj = " +adj);
                //ua_mdl_trace("[vertex] vertno=%u vertex=(%f,%f,%f) z from=%u",
                //  vertno,refvect.x,refvect.y,refvect.z,refvert);
                break;
            }


            case nodecmd.M3_UW_VERTEX_Y: // 008a define vertex offset Y
            {
                writer.WriteLine("\nInstr " + instr + " offsetY");
                int   refvert = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;
                float vy      = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;//ua_mdl_read_fixed(fd);
                int   vertno  = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;

                Vector3 refvect = mod.verts[refvert];
                //refvect.y += vy;
                //refvect  = new Vector3(refvect.x,refvect.y+(float)vy,refvect.z);
                Vector3 adj = new Vector3(0f, vy, 0f);
                ua_mdl_store_vertex(refvect + adj, vertno, ref mod);
                // Debug.Log("Vertex offsetY #" +(vertno) + "="  + (refvect+adj) + " from " + refvect + "(" + refvert + ")" + " adj = " +adj);
                // ua_mdl_trace("[vertex] vertno=%u vertex=(%f,%f,%f) y from=%u",
                //   vertno,refvect.x,refvect.y,refvect.z,refvert);
                break;
            }


            case nodecmd.M3_UW_VERTEX_XZ: // 0090 define vertex offset X,Z
            {
                writer.WriteLine("\nInstr " + instr + " offsetXZ");
                float vx      = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2; //ua_mdl_read_fixed(fd);
                float vz      = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2; //ua_mdl_read_fixed(fd);
                int   refvert = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;
                int   vertno  = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;

                Vector3 refvect = mod.verts[refvert];
                //refvect.x += vx;
                //refvect.z += vz;
                // refvect  = new Vector3(refvect.x+(float)vx,refvect.y,refvect.z+(float)vz);
                Vector3 adj = new Vector3(vx, 0f, vz);
                ua_mdl_store_vertex(refvect + adj, vertno, ref mod);
                // Debug.Log("Vertex offsetXZ #" +(vertno) + "="  + (refvect+adj) + " from " + refvect + "(" + refvert + ")" + " adj = " +adj);
                // ua_mdl_trace("[vertex] vertno=%u vertex=(%f,%f,%f) xz from=%u",
                //    vertno,refvect.x,refvect.y,refvect.z,refvert);
                break;
            }


            case nodecmd.M3_UW_VERTEX_XY: // 0092 define vertex offset X,Y
            {
                writer.WriteLine("\nInstr " + instr + " offsetXY");
                float vx      = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2; //ua_mdl_read_fixed(fd);
                float vy      = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2; //ua_mdl_read_fixed(fd);
                int   refvert = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;
                int   vertno  = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;

                Vector3 refvect = mod.verts[refvert];
                // refvect.x += vx;
                //  refvect.y += vy;
                //refvect  = new Vector3(refvect.x+(float)vx,refvect.y+(float)vy,refvect.z);
                // ua_mdl_store_vertex(refvect,vertno,ref mod);
                Vector3 adj = new Vector3(vx, vy, 0f);
                ua_mdl_store_vertex(refvect + adj, vertno, ref mod);
                // Debug.Log("Vertex offsetXY #" +(vertno) + "="  + (refvect+adj) + " from " + refvect + "(" + refvert + ")" + " adj = " +adj);
                // ua_mdl_trace("[vertex] vertno=%u vertex=(%f,%f,%f) xy from=%u",
                //   vertno,refvect.x,refvect.y,refvect.z,refvert);
                break;
            }


            case nodecmd.M3_UW_VERTEX_YZ: // 0094 define vertex offset Y,Z
            {
                writer.WriteLine("\nInstr " + instr + " offsetYZ");
                float vy      = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2; //ua_mdl_read_fixed(fd);
                float vz      = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2; //ua_mdl_read_fixed(fd);
                int   refvert = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;
                int   vertno  = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;

                Vector3 refvect = mod.verts[refvert];
                //refvect.y += vy;
                // refvect.z += vz;
                //refvect  = new Vector3(refvect.x,refvect.y+(float)vy,refvect.z+(float)vz);
                // ua_mdl_store_vertex(refvect,vertno,ref mod);
                Vector3 adj = new Vector3(0f, vy, vz);
                ua_mdl_store_vertex(refvect + adj, vertno, ref mod);
                // Debug.Log("Vertex offsetYZ #" +(vertno) + "="  + (refvect+adj) + " from " + refvect + "(" + refvert + ")" + " adj = " +adj);

                // ua_mdl_trace("[vertex] vertno=%u vertex=(%f,%f,%f) yz from=%u",
                //    vertno,refvect.x,refvect.y,refvect.z,refvert);
                break;
            }


            case nodecmd.M3_UW_VERTEX_CEIL: // 008c define vertex variable height
            {
                writer.WriteLine("\nInstr " + instr + " UW_VERTEX_CEIL");
                int refvert = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;
                int unk1    = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2;//fread16(fd);
                int vertno  = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;

                Vector3 refvect = mod.verts[refvert];
                // refvect.z = 32.0f; // todo: ceiling value
                //refvect  = new Vector3(refvect.x,refvect.y,32f);
                Vector3 adj = new Vector3(0f, 0f, 32f);
                ua_mdl_store_vertex(refvect + adj, vertno, ref mod);
                //  writer.WriteLine("\tVertex Ceil #" +(vertno) + "="  + (refvect+adj) + " from " + refvect + "(" + refvert + ")" + " adj = " +adj);
                //  ua_mdl_trace("[vertex] vertno=%u vertex=(%f,%f,ceil) ceil from=%u unk1=%04x",
                //   vertno,refvect.x,refvect.y,refvert,unk1);
                break;
            }

            // face plane checks
            case nodecmd.M3_UW_FACE_PLANE: // 0058 define face plane, arbitrary heading
            {
                writer.WriteLine("\nInstr " + instr + " UW_FACE_PLANE");
                int   unk1 = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; //fread16(fd);
                float nx   = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                   //ua_mdl_read_fixed(fd);
                float vx   = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                   //ua_mdl_read_fixed(fd);
                float ny   = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                   //ua_mdl_read_fixed(fd);
                float vy   = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                   //ua_mdl_read_fixed(fd);
                float nz   = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                   //ua_mdl_read_fixed(fd);
                float vz   = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                   //ua_mdl_read_fixed(fd);
                writer.Write("\t Normal (" + nx + "," + ny + "," + nz + ") dist (" + vx + "," + vy + "," + vz + ")\n");
                //  ua_mdl_trace("[planecheck] skip=%04x normal=(%f,%f,%f) dist=(%f,%f,%f)",
                //    unk1,nx,ny,nz,vx,vy,vz);
                break;
            }


            case nodecmd.M3_UW_FACE_PLANE_X: // 0064 define face plane X
            case nodecmd.M3_UW_FACE_PLANE_Z: // 0066 define face plane Z
            case nodecmd.M3_UW_FACE_PLANE_Y: // 0068 define face plane Y
            {
                writer.WriteLine("\nInstr " + instr + " UW_FACE_PLANE (x/z/y)");
                int   unk1 = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; //fread16(fd);
                float nx   = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                   //ua_mdl_read_fixed(fd);
                float vx   = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                   //ua_mdl_read_fixed(fd);
                writer.Write("\t Normal (" + nx + ") dist (" + vx + ")\n");

                // ua_mdl_trace("[planecheck] skip=%04x normal=(%f,%f,%f) dist=(%f,%f,%f) %c",
                // unk1,
                //cmd == nodecmd.M3_UW_FACE_PLANE_X ? nx : 0.0,
                // cmd == nodecmd.M3_UW_FACE_PLANE_Y ? nx : 0.0,
                //cmd == nodecmd.M3_UW_FACE_PLANE_Z ? nx : 0.0,
                //cmd == nodecmd.M3_UW_FACE_PLANE_X ? vx : 0.0,
                //cmd == nodecmd.M3_UW_FACE_PLANE_Y ? vx : 0.0,
                //cmd == nodecmd.M3_UW_FACE_PLANE_Z ? vx : 0.0,

                // cmd == M3_UW_FACE_PLANE_X ? 'x' : cmd == M3_UW_FACE_PLANE_Y ? 'y' : 'z'
                //);
                break;
            }


            case nodecmd.M3_UW_FACE_PLANE_ZY: // 005e define face plane Z/Y
            case nodecmd.M3_UW_FACE_PLANE_XY: // 0060 define face plane X/Y
            case nodecmd.M3_UW_FACE_PLANE_XZ: // 0062 define face plane X/Z
            {
                writer.WriteLine("\nInstr " + instr + " UW_FACE_PLANE (zy/xy/xz)");
                int   unk1 = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; // fread16(fd);
                float nx   = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                   //ua_mdl_read_fixed(fd);
                float vx   = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                   // ua_mdl_read_fixed(fd);
                float ny   = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                   //ua_mdl_read_fixed(fd);
                float vy   = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                   //ua_mdl_read_fixed(fd);
                writer.Write("\t Normal (" + nx + "," + ny + ") dist (" + vx + "," + vy + ")\n");
                //ua_mdl_trace("[planecheck] skip=%04x ",unk1);

                /*if (dump)
                 * switch(cmd)
                 * {
                 * case nodecmd.M3_UW_FACE_PLANE_ZY:
                 * // ua_mdl_trace("normal=(%f,%f,%f) dist=(%f,%f,%f) zy",0.0,ny,nx,0.0,vy,vx);
                 * break;
                 * case nodecmd.M3_UW_FACE_PLANE_XY:
                 * // ua_mdl_trace("normal=(%f,%f,%f) dist=(%f,%f,%f) xy",nx,ny,0.0,vx,vy,0.0);
                 * break;
                 * case nodecmd.M3_UW_FACE_PLANE_XZ:
                 * //  ua_mdl_trace("normal=(%f,%f,%f) dist=(%f,%f,%f) xz",nx,0.0,ny,vx,0.0,vy);
                 * break;
                 * }*/
                break;
            }


            // face info nodes
            case nodecmd.M3_UW_FACE_VERTICES: // 007e define face vertices
            {
                writer.WriteLine("\nInstr " + instr + " UW_FACE_VERTICES");
                int nvert = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2;//fread16(fd);
                //Xua_poly_tessellator tess;
                string output = "\tFace Verts are :";
                // ua_mdl_trace("[face] nvert=%u vertlist=",nvert);
                int[] faceverts = new int[nvert];
                for (int i = 0; i < nvert; i++)
                {
                    // Uint16
                    int vertno = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;

                    // mod.tris.Add(vertno);//moved
                    faceverts[i] = vertno;
                    //Xua_vertex3d vert;
                    output = output + vertno + ",";
                    //
                    //X vert.pos = mod.verts[vertno];
                    //X tess.add_poly_vertex(vert);

                    //ua_mdl_trace("%u",vertno);
                    //if (i<=nvert-1) ua_mdl_trace(" ");
                }

                //X  const std::vector<ua_triangle3d_textured>& tri = tess.tessellate(0x0001);
                //triangles.insert(triangles.begin(),tri.begin(),tri.end());
                //mod.tris.Add(vertno);
                writer.WriteLine(output);
                convertVertToTris(faceverts, ref mod);
            }
            break;

            case nodecmd.M3_UW_TEXTURE_FACE:  // 00a8 define texture-mapped face
            case nodecmd.M3_UW_TMAP_VERTICES: // 00b4 define face vertices with u,v information
            {
                writer.WriteLine("\nInstr " + instr + " UW_TEXTURE_FACE or UW_TMAP_VERTICES");
                // ua_mdl_trace("[face] %s ",cmd==M3_UW_TEXTURE_FACE ? "tex" : "tmap");
                string output = "\tFace Verts are :";
                // read texture number
                if ((nodecmd)cmd == nodecmd.M3_UW_TEXTURE_FACE)
                {
                    int unk1 = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2;//fread16(fd); // texture number?
                    //ua_mdl_trace("texnum=%04x ",unk1);
                }

                int nvert = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2;//fread16(fd);
                //X ua_poly_tessellator tess;

                //ua_mdl_trace("nvert=%u vertlist=",nvert);
                int[] faceverts = new int[nvert];
                for (int i = 0; i < nvert; i++)
                {
                    // Uint16
                    int vertno = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;
                    output = output + vertno + ",";
                    float u0 = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2; //ua_mdl_read_fixed(fd);
                    float v0 = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2; //ua_mdl_read_fixed(fd);

                    // mod.tris.Add(vertno);//moved
                    faceverts[i] = vertno;
                    //X ua_vertex3d vert;
                    //X vert.pos = mod.verts[vertno];
                    //X vert.u = u0;
                    //X vert.v = v0;
                    //X tess.add_poly_vertex(vert);

                    //ua_mdl_trace("%u (%f/%f)",vertno,u0,v0);
                    // if (i<=nvert-1) ua_mdl_trace(" ");
                }
                writer.WriteLine(output);
                convertVertToTris(faceverts, ref mod);
                //X const std::vector<ua_triangle3d_textured>& tri = tess.tessellate(0x0002);
                //X triangles.insert(triangles.begin(),tri.begin(),tri.end());
            }
            break;

            // sort nodes
            case nodecmd.M3_UW_SORT_PLANE: // 0006 define sort node, arbitrary heading

            // fall-through

            case nodecmd.M3_UW_SORT_PLANE_ZY: // 000C define sort node, ZY plane
            case nodecmd.M3_UW_SORT_PLANE_XY: // 000E define sort node, XY plane
            case nodecmd.M3_UW_SORT_PLANE_XZ: // 0010 define sort node, XZ plane
            {
                writer.WriteLine("\nInstr " + instr + " SORT PLANES");
                if ((nodecmd)(cmd) == nodecmd.M3_UW_SORT_PLANE)
                {
                    float nx = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2; //ua_mdl_read_fixed(fd);
                    float vx = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2; //ua_mdl_read_fixed(fd);
                }

                float ny = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                //ua_mdl_read_fixed(fd);
                float vy = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                //ua_mdl_read_fixed(fd);
                float nz = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                //ua_mdl_read_fixed(fd);
                float vz = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;                //ua_mdl_read_fixed(fd);

                long left = DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2;  //fread16(fd);
                left += addressptr;                                                                  // ftell(fd);

                long right = DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; //fread16(fd);
                right += addressptr;                                                                 // ftell(fd);

                long here = addressptr;                                                              //ftell(fd);

                // parse left nodes
                //fseek(fd,left,SEEK_SET);
                addressptr = here;
                ua_model_parse_node(modelfile, addressptr, ref mod, dump);
                //ua_model_parse_node(fd,origin,vertex_list,triangles,dump);

                // ua_mdl_trace("      [sort] end left node/start right node\n");

                // parse right nodes
                //  fseek(fd,right,SEEK_SET);
                addressptr = right;
                ua_model_parse_node(modelfile, addressptr, ref mod, dump);
                //ua_model_parse_node(fd,origin,vertex_list,triangles,dump);

                // return to "here"
                //  fseek(fd,here,SEEK_SET);
                addressptr = here;

                // ua_mdl_trace("      [sort] end");
            }
            break;

            // unknown nodes
            case nodecmd.M3_UW_COLOR_DEF: // 0014 ??? colour definition
            {
                writer.WriteLine("\nInstr " + instr + " UW_COLOR_DEF");
                int refvert = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;
                int unk1    = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2;//fread16(fd);
                int vertno  = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;
                // ua_mdl_trace("[shade] color refvert=%u unk1=%04x vertno=%u",refvert,unk1,vertno);
                break;
            }


            case nodecmd.M3_UW_FACE_SHADE: // 00BC define face shade
            {
                writer.WriteLine("\nInstr " + instr + " UW_FACE_SHADE");
                int unk1   = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; //fread16(fd);
                int vertno = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; //fread16(fd);
                //ua_mdl_trace("[shade] shade unk1=%02x unk2=%02x",unk1,vertno);
                break;
            }


            case nodecmd.M3_UW_FACE_TWOSHADES: // 00BE ??? seems to define 2 shades
            {
                writer.WriteLine("\nInstr " + instr + " UW_FACE_TWOSHADES");
                int vertno = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; //fread16(fd);
                int unk1   = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; //fread16(fd);
                //ua_mdl_trace("[shade] twoshade unk1=%02x unk2=%02x ",vertno,unk1);
                break;
            }


            case nodecmd.M3_UW_VERTEX_DARK: // 00D4 define dark vertex face (?)
            {
                writer.WriteLine("\nInstr " + instr + " UW_VERTEX_DARK");
                int nvert = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; // fread16(fd);
                int unk1  = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; // fread16(fd);

                //ua_mdl_trace("[shade] color nvert=%u, unk1=%04x vertlist=",
                //  nvert,unk1);

                for (int n = 0; n < nvert; n++)
                {
                    int vertno = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;
                    // unk1 = fgetc(fd);
                    addressptr++;

                    // ua_mdl_trace("%u (%02x) ",vertno,unk1);
                }


                if ((nvert & 1) == 1)
                {
                    // fgetc(fd); // read alignment padding
                    addressptr++;
                }
            }
            break;

            case nodecmd.M3_UW_FACE_GOURAUD: // 00D6 define gouraud shading
                // ua_mdl_trace("[shade] gouraud");
                writer.WriteLine("\nInstr " + instr + " UW_FACE_GOURAUD");
                break;

            case nodecmd.M3_UW_FACE_UNK40: // 0040 ???
                writer.WriteLine("\nInstr " + instr + " UW_FACE_UNK40");
                // ua_mdl_trace("[shade] unknown");
                break;

            case nodecmd.M3_UW_FACE_SHORT: // 00A0 ??? shorthand face definition
            {
                writer.WriteLine("\nInstr " + instr + " UW_FACE_SHORT");
                int vertno = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;
                //X ua_poly_tessellator tess;
                string output = "\t";
                //ua_mdl_trace("[face] shorthand unk1=%u vertlist=",vertno);
                int[] faceverts = new int[4];
                for (int i = 0; i < 4; i++)
                {
                    vertno       = (int)DataLoader.getValAtAddress(modelfile, addressptr, 8); addressptr++; //fgetc(fd);
                    output       = output + vertno + ",";
                    faceverts[i] = vertno;
                }
                writer.WriteLine(output);
                convertVertToTris(faceverts, ref mod);
                //X const std::vector<ua_triangle3d_textured>& tri = tess.tessellate(0x0003);
                //triangles.insert(triangles.begin(),tri.begin(),tri.end());
            }
            break;

            case (nodecmd)0x00d2: // 00D2 ??? shorthand face definition
            {
                writer.WriteLine("\nInstr " + instr + " UW_SHORTHAND_FACE_DEFINITION");
                int vertno = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;
                //X            ua_poly_tessellator tess;
                string output = "\t";
                //ua_mdl_trace("[face] vertno=%u vertlist=",vertno);
                int[] faceverts = new int[4];
                for (int i = 0; i < 4; i++)
                {
                    vertno       = (int)DataLoader.getValAtAddress(modelfile, addressptr, 8); addressptr++; //fgetc(fd);
                    output       = output + vertno + ",";
                    faceverts[i] = vertno;
                }
                writer.WriteLine(output);
                convertVertToTris(faceverts, ref mod);
                //X const std::vector<ua_triangle3d_textured>& tri = tess.tessellate(0x0004);
                // triangles.insert(triangles.begin(),tri.begin(),tri.end());

                //ua_mdl_trace("shorthand");
            }
            break;

            case nodecmd.M3_UW_FACE_UNK16: // 0016 ???
            {
                writer.WriteLine("\nInstr " + instr + " UW_FACE_UNK16");
                long pos = addressptr;                                                                   //(int)DataLoader.getValAtAddress(modelfile,addressptr,16);addressptr++;//ftell(fd);

                int nvert = ua_mdl_read_vertno(modelfile, addressptr); addressptr += 2;                  //ua_mdl_read_vertno(fd);
                int unk1  = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2; //fread16(fd);

                for (int n = 0; n < nvert; n++)
                {
                    // unk1 = fgetc(fd);
                    addressptr++;
                }

                if ((nvert & 1) == 1)
                {
                    addressptr++;
                }
                //fgetc(fd); // read alignment padding
            }
            break;

            case (nodecmd)0x0012:
            {
                writer.WriteLine("\nInstr " + instr + " UNK 12");
                int unk1 = (int)DataLoader.getValAtAddress(modelfile, addressptr, 16); addressptr += 2;//fread16(fd);
                break;
            }

            default:
                //ua_mdl_trace("unknown command at offset 0x%08x\n",ftell(fd)-2);
                writer.WriteLine("\nInstr " + instr + " UNKNOWN CMD returning");
                return;
            }
            // ua_mdl_trace("\n");
        }
    }
예제 #5
0
    void DecodeModel(string filePath)
    {
        char[] modelfile;
        if (!DataLoader.ReadStreamFile(filePath, out modelfile))
        {
            return;
        }
        long baseOffset = 0; // models list base address
        long addressptr = 0;

        // search all offsets for model table begin
        // long max =; //SDL_TABLESIZE(ua_model_offset_table);
        for (int i = 0; i <= modeltable.GetUpperBound(0); i++)
        {
            // check value on file position
            //fseek(fd,ua_model_offset_table[i].table_offset,SEEK_SET);
            // Uint32 file_value = fread32(fd);
            long file_value = DataLoader.getValAtAddress(modelfile, modeltable[i].table_offset, 32);
            if (file_value == modeltable[i].value)
            {
                // found position
                baseOffset = modeltable[i].base_offset;
                // fseek(fd,ua_model_offset_table[i].table_offset,SEEK_SET);
                addressptr = modeltable[i].table_offset;
                //ua_trace("found models in %s at 0x%08x\n",filename,base);
                //Debug.Log("Found models at " + baseOffset);
                break;
            }
        }

        if (baseOffset == 0)
        {
            Debug.Log("didn't find models in file\n");
            return; // didn't find list
        }



        // read in offsets
        long[] offsets = new long[32];

        for (int j = 0; j <= offsets.GetUpperBound(0); j++)
        {
            offsets[j]  = DataLoader.getValAtAddress(modelfile, addressptr, 16);//fread16(fd);
            addressptr += 2;
        }

        UWModel[] models = new UWModel[32];

        // parse all models
        for (int n = 0; n <= offsets.GetUpperBound(0); n++)
        {
            // seek to model
            //fseek(fd,base + offsets[n],SEEK_SET);

            addressptr = baseOffset + offsets[n];
            // read header
            //Uint32 unk1 = fread32(fd);
            long unk1 = DataLoader.getValAtAddress(modelfile, addressptr, 32);
            addressptr += 4;
            // extents
            float ex = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;
            float ey = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;
            float ez = ua_mdl_read_fixed(modelfile, addressptr); addressptr += 2;

            Vector3 extents = new Vector3((float)ex, (float)ez, (float)ey);
            //ua_vector3d extents(ex,ez,ey);

            // ua_mdl_trace("dumping builtin model %u (%s)\noffset=0x%08x [unk1=0x%04x, extents=(%f,%f,%f) ]\n",
            //  n,ua_model_name[n],base + offsets[n],unk1,ex,ey,ez);

            //ua_model3d_builtin* model = new ua_model3d_builtin;

            models[n].tris      = new List <int>();
            models[n].verts     = new List <Vector3>();
            models[n].modelname = ua_model_name[n];
            // Debug.Log(models[n].modelname);
            for (int i = 0; i <= 128; i++)
            {
                models[n].verts.Add(Vector3.zero);
            }

            // temporary variables
            // ua_vector3d origin;

            //std::vector<ua_vector3d> vertex_list;

            // parse root node
            //ua_model_parse_node(fd, origin, vertex_list, model->triangles, dump);
            if (n == modelToLoad)
            {
                writer.WriteLine("Loading model " + ua_model_name[n] + " at " + addressptr);
                ua_model_parse_node(modelfile, addressptr, ref models[n], true);
            }


            //x   ua_mdl_trace("\n");

            //x /*model->*/origin.z -= extents.z/2.0;
            //x   model->extents = extents;

            // insert model
            //x ua_model3d_ptr model_ptr(model);
            //x allmodels.push_back(model_ptr);
        }
        RenderModel(models[modelToLoad]);
    }