コード例 #1
0
        private static GeometryModel3D DrawModel(Vertex[] verts, Int32[] indices, Material material)
        {
            var mesh = new MeshGeometry3D();

            for (int k = 0; k < verts.Length; k++)
            {
                Vertex v = verts[k];

                if (v.Position != null)
                {
                    mesh.Positions.Add(new Point3D(v.Position[0], -v.Position[2], v.Position[1]));
                }
                if (v.Normal != null)
                {
                    mesh.Normals.Add(new Vector3D(v.Normal[0], v.Normal[1], v.Normal[2]));
                }
                if (v.UV != null && v.UV.Length > 0)
                {
                    mesh.TextureCoordinates.Add(new Point(v.UV[0][0], v.UV[0][1]));
                }
            }
            for (int i = 0; i < indices.Length; i++)
            {
                mesh.TriangleIndices.Add(indices[i]);
            }
            return(new GeometryModel3D(mesh, material));
        }
コード例 #2
0
ファイル: VBUF.cs プロジェクト: dd-dk/s3pi
 public bool SetVertices(MLOD mlod, MLOD.Mesh mesh, MLOD.GeometryState geo, VRTF vrtf, Vertex[] vertices, float[] uvscales)
 {
     long beforeLength = mesh.StreamOffset + (geo.MinVertexIndex * vrtf.Stride);
     bool okay = SetVertices(mlod, mesh.VertexBufferIndex, beforeLength, geo.VertexCount, vrtf, vertices, uvscales);
     geo.VertexCount = vertices.Length;
     return okay;
 }
コード例 #3
0
ファイル: VBUF.cs プロジェクト: dd-dk/s3pi
 public bool SetVertices(MLOD mlod, MLOD.Mesh mesh, int geoIndex, VRTF vrtf, Vertex[] vertices, float[] uvscales)
 {
     return SetVertices(mlod, mesh, mesh.GeometryStates[geoIndex], vrtf, vertices, uvscales);
 }
コード例 #4
0
ファイル: VBUF.cs プロジェクト: dd-dk/s3pi
 public bool SetVertices(MLOD mlod, MLOD.Mesh mesh, VRTF vrtf, Vertex[] vertices, float[] uvscales)
 {
     bool okay = SetVertices(mlod, mesh.VertexBufferIndex, mesh.StreamOffset, mesh.VertexCount, vrtf, vertices, uvscales);
     mesh.VertexCount = vertices.Length;
     return okay;
 }
コード例 #5
0
ファイル: VBUF.cs プロジェクト: dd-dk/s3pi
 public bool SetVertices(MLOD mlod, int meshIndex, VRTF vrtf, Vertex[] vertices, float[] uvscales)
 {
     return SetVertices(mlod, mlod.Meshes[meshIndex], vrtf, vertices, uvscales);
 }
コード例 #6
0
ファイル: VBUF.cs プロジェクト: dd-dk/s3pi
        public Vertex[] GetVertices(VRTF vrtf, long offset, int count, float[] uvscales)
        {
            long streamOffset = offset;
            Stream s = new MemoryStream(mBuffer);
            s.Seek(streamOffset, SeekOrigin.Begin);

            var position = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Position);
            var normal = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Normal);
            var uv = vrtf.Layouts
                .Where(x => x.Usage == VRTF.ElementUsage.UV)
                .ToArray();
            var blendIndices = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendIndex);
            var blendWeights = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.BlendWeight);
            var tangents = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Tangent);
            var color = vrtf.Layouts
                .FirstOrDefault(x => x.Usage == VRTF.ElementUsage.Colour);

            Vertex[] verts = new Vertex[count];
            if (uvscales == null) uvscales = new float[3];
            for (int i = 0; i < count; i++)
            {
                Vertex v = new Vertex();
                byte[] data = new byte[vrtf.Stride];
                s.Read(data, 0, vrtf.Stride);
                if (position != null)
                {
                    float[] posPoints = new float[VRTF.FloatCountFromFormat(position.Format)];
                    ReadFloatData(data, position, ref posPoints);
                    v.Position = posPoints;
                }
                if (normal != null)
                {
                    float[] normPoints = new float[VRTF.FloatCountFromFormat(normal.Format)];
                    ReadFloatData(data, normal, ref normPoints);
                    v.Normal = normPoints;
                }
                v.UV = new float[uv.Length][];
                for (int j = 0; j < uv.Length; j++)
                {
                    var u = uv[j];
                    float[] uvPoints = new float[VRTF.FloatCountFromFormat(u.Format)];
                    var scale = j < uvscales.Length && uvscales[j] != 0 ? uvscales[j] : uvscales[0];
                    ReadUVData(data, u, ref uvPoints, scale);
                    v.UV[j] = uvPoints;
                }
                if (blendIndices != null)
                {
                    byte[] blendIPoints = new byte[VRTF.ByteSizeFromFormat(blendIndices.Format)];
                    Array.Copy(data, blendIndices.Offset, blendIPoints, 0, blendIPoints.Length);
                    v.BlendIndices = blendIPoints;
                }
                if (blendWeights != null)
                {
                    float[] blendWPoints = new float[VRTF.FloatCountFromFormat(blendWeights.Format)];
                    ReadFloatData(data, blendWeights, ref blendWPoints);
                    v.BlendWeights = blendWPoints;
                }
                if (tangents != null)
                {
                    float[] tangentPoints = new float[VRTF.FloatCountFromFormat(tangents.Format)];
                    ReadFloatData(data, tangents, ref tangentPoints);
                    v.Tangents = tangentPoints;
                }
                if (color != null)
                {
                    float[] colorPoints = new float[VRTF.FloatCountFromFormat(color.Format)];
                    ReadFloatData(data, color, ref colorPoints);
                    v.Color = colorPoints;
                }
                verts[i] = v;
            }
            return verts;
        }
コード例 #7
0
        public static meshExpImp.ModelBlocks.Vertex[] Import_VBUF(this StreamReader r, MyProgressBar mpb, int count, VRTF vrtf)
        {
            meshExpImp.ModelBlocks.Vertex[] vertices = new meshExpImp.ModelBlocks.Vertex[count];
            int uvLength = vrtf.Layouts.FindAll(x => x.Usage == VRTF.ElementUsage.UV).Count;

            int line = 0;

            mpb.Init("Import VBUF...", count);
            for (int v = 0; v < count; v++)
            {
                meshExpImp.ModelBlocks.Vertex vertex = new meshExpImp.ModelBlocks.Vertex();
                int nUV = 0;
                vertex.UV = new float[uvLength][];

                foreach (var layout in vrtf.Layouts)
                {
                    string[] split = r.ReadLine().Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
                    if (split.Length < 2)
                    {
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has invalid format.", line));
                    }
                    int index;
                    if (!int.TryParse(split[0], out index))
                    {
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has invalid line index.", line));
                    }
                    if (index != v)
                    {
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has incorrect line index value {1}.", line, index));
                    }
                    byte usage;
                    if (!byte.TryParse(split[1], out usage))
                    {
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has invalid Usage.", v));
                    }
                    if (usage != (byte)layout.Usage)
                    {
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has incorrect line Usage value {1}.", line, usage));
                    }

                    switch (usage)
                    {
                    case (byte)VRTF.ElementUsage.Position:
                        vertex.Position = GetFloats(layout.Format, line, split.ConvertAll <Single>(2));
                        break;

                    case (byte)VRTF.ElementUsage.Normal:
                        vertex.Normal = GetFloats(layout.Format, line, split.ConvertAll <Single>(2));
                        break;

                    case (byte)VRTF.ElementUsage.UV:
                        vertex.UV[nUV++] = GetFloats(layout.Format, line, split.ConvertAll <Single>(2));
                        break;

                    case (byte)VRTF.ElementUsage.BlendIndex:
                        byte[] BlendIndices = split.ConvertAll <byte>(2);
                        if (!(BlendIndices.Length == VRTF.ByteSizeFromFormat(layout.Format) || BlendIndices.Length + 1 == VRTF.ByteSizeFromFormat(layout.Format)))
                        {
                            throw new InvalidDataException(string.Format("'vbuf' line {0} has incorrect format.", line));
                        }
                        vertex.BlendIndices = BlendIndices;
                        break;

                    case (byte)VRTF.ElementUsage.BlendWeight:
                        vertex.BlendWeights = GetFloats(layout.Format, line, split.ConvertAll <Single>(2));
                        break;

                    case (byte)VRTF.ElementUsage.Tangent:
                        vertex.Tangents = GetFloats(layout.Format, line, split.ConvertAll <Single>(2));
                        break;

                    case (byte)VRTF.ElementUsage.Colour:
                        vertex.Color = GetFloats(layout.Format, line, split.ConvertAll <Single>(2));
                        break;
                    }
                    line++;
                }
                vertices[v] = vertex;
                if (nUV != uvLength)
                {
                    throw new InvalidDataException(string.Format("'vbuf' vertex {0} read {1} UV lines, expected {2}.", v, nUV, uvLength));
                }
                mpb.Value++;
            }
            mpb.Done();

            return(vertices);
        }
コード例 #8
0
        public static void Export_VBUF(this StreamWriter w, MyProgressBar mpb, meshExpImp.ModelBlocks.Vertex[] av, VRTF vrtf)
        {
            mpb.Init("Export VBUF...", av.Length);
            for (int i = 0; i < av.Length; i++)
            {
                meshExpImp.ModelBlocks.Vertex v = av[i];
                int nUV = 0;
                foreach (var layout in vrtf.Layouts)
                {
                    w.Write(string.Format("{0} {1}", i, (byte)layout.Usage));
                    switch (layout.Usage)
                    {
                    case VRTF.ElementUsage.Position:
                        if (v.Position != null)
                        {
                            foreach (float f in v.Position)
                            {
                                w.Write(string.Format(" {0:F6}", f));
                            }
                        }
                        else
                        {
                            w.Write(" Position is null.");
                        }
                        break;

                    case VRTF.ElementUsage.Normal:
                        if (v.Normal != null)
                        {
                            foreach (float f in v.Normal)
                            {
                                w.Write(string.Format(" {0:F6}", f));
                            }
                        }
                        else
                        {
                            w.Write(" Normal is null.");
                        }
                        break;

                    case VRTF.ElementUsage.UV:
                        if (v.UV != null)
                        {
                            foreach (float f in v.UV[nUV])
                            {
                                w.Write(string.Format(" {0:F6}", f));
                            }
                        }
                        else
                        {
                            w.Write(string.Format(" UV[{0}] is null.", nUV));
                        }
                        nUV++;
                        break;

                    case VRTF.ElementUsage.BlendIndex:
                        if (v.BlendIndices != null)
                        {
                            foreach (byte b in v.BlendIndices)
                            {
                                w.Write(string.Format(" {0}", b));
                            }
                        }
                        else
                        {
                            w.Write(" BlendIndices is null.");
                        }
                        break;

                    case VRTF.ElementUsage.BlendWeight:
                        if (v.BlendWeights != null)
                        {
                            foreach (float f in v.BlendWeights)
                            {
                                w.Write(string.Format(" {0:F6}", f));
                            }
                        }
                        else
                        {
                            w.Write(" BlendWeight is null.");
                        }
                        break;

                    case VRTF.ElementUsage.Tangent:
                        if (v.Tangents != null)
                        {
                            foreach (float f in v.Tangents)
                            {
                                w.Write(string.Format(" {0:F6}", f));
                            }
                        }
                        else
                        {
                            w.Write(" Tangents is null.");
                        }
                        break;

                    case VRTF.ElementUsage.Colour:
                        if (v.Color != null)
                        {
                            foreach (float f in v.Color)
                            {
                                w.Write(string.Format(" {0:F6}", f));
                            }
                        }
                        else
                        {
                            w.Write(" Colour is null.");
                        }
                        break;
                    }
                    w.WriteLine();
                    mpb.Value++;
                }
            }

            w.Flush();
            mpb.Done();
        }
コード例 #9
0
        private void InitScene()
        {
            GeostatesPanel.Visibility = Visibility.Collapsed;
            GenericRCOLResource.ChunkEntry chunk = rcol.ChunkEntries.FirstOrDefault(x => x.RCOLBlock is MLOD);

            int polyCount = 0;
            int vertCount = 0;


            if (chunk != null)
            {
                var mlod = chunk.RCOLBlock as MLOD;
                foreach (MLOD.Mesh m in mlod.Meshes)
                {
                    try
                    {
                        vertCount += m.VertexCount;
                        polyCount += m.PrimitiveCount;
                        var        vbuf     = (VBUF)GenericRCOLResource.ChunkReference.GetBlock(rcol, m.VertexBufferIndex);
                        var        ibuf     = (IBUF)GenericRCOLResource.ChunkReference.GetBlock(rcol, m.IndexBufferIndex);
                        VRTF       vrtf     = (VRTF)GenericRCOLResource.ChunkReference.GetBlock(rcol, m.VertexFormatIndex) ?? VRTF.CreateDefaultForMesh(m);
                        IRCOLBlock material = GenericRCOLResource.ChunkReference.GetBlock(rcol, m.MaterialIndex);

                        MATD matd = FindMainMATD(rcol, material);

                        float[] uvscale = GetUvScales(matd);
                        if (uvscale != null)
                        {
                            Debug.WriteLine(string.Format("{0} - {1} - {2}", uvscale[0], uvscale[2], uvscale[2]));
                        }
                        else
                        {
                            Debug.WriteLine("No scales");
                        }

                        GeometryModel3D model = DrawModel(vbuf.GetVertices(m, vrtf, uvscale), ibuf.GetIndices(m), mNonSelectedMaterial);

                        var sceneMesh = new SceneMlodMesh(m, model);
                        if (matd != null)
                        {
                            sceneMesh.Shader = matd.Shader;
                            switch (matd.Shader)
                            {
                            case ShaderType.ShadowMap:
                            case ShaderType.DropShadow:
                                break;

                            default:
                                var maskWidth  = GetMATDParam <ElementInt>(matd, FieldType.MaskWidth);
                                var maskHeight = GetMATDParam <ElementInt>(matd, FieldType.MaskHeight);
                                if (maskWidth != null && maskHeight != null)
                                {
                                    float scalar = Math.Max(maskWidth.Data, maskHeight.Data);
                                    mCheckerBrush.Transform = new ScaleTransform(maskHeight.Data / scalar, maskWidth.Data / scalar);
                                }
                                break;
                            }
                        }
                        try
                        {
                            var sceneGeostates = new SceneGeostate[m.GeometryStates.Count];
                            for (int i = 0; i < sceneGeostates.Length; i++)
                            {
                                GeometryModel3D state = DrawModel(vbuf.GetVertices(m, vrtf, m.GeometryStates[i], uvscale),
                                                                  ibuf.GetIndices(m, m.GeometryStates[i]), mHiddenMaterial);
                                mGroupMeshes.Children.Add(state);
                                sceneGeostates[i] = new SceneGeostate(sceneMesh, m.GeometryStates[i], state);
                            }
                            sceneMesh.States = sceneGeostates;
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("Unable to load Geostates.  You may have some corrupted data: " + ex.ToString(),
                                            "Unable to load Geostates...");
                        }
                        mGroupMeshes.Children.Add(model);
                        mSceneMeshes.Add(sceneMesh);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(String.Format("Unable to load mesh id 0x{0:X8}", m.Name));
                    }
                }
            }
            else
            {
                GenericRCOLResource.ChunkEntry geomChunk = rcol.ChunkEntries.FirstOrDefault();
                var geom  = new GEOM(0, null, geomChunk.RCOLBlock.Stream);
                var verts = new List <Vertex>();
                polyCount = geom.Faces.Count;
                vertCount = geom.VertexData.Count;
                foreach (GEOM.VertexDataElement vd in geom.VertexData)
                {
                    var v = new Vertex();

                    var pos = (GEOM.PositionElement)vd.Vertex.FirstOrDefault(e => e is GEOM.PositionElement);
                    if (pos != null)
                    {
                        v.Position = new[] { pos.X, pos.Y, pos.Z };
                    }


                    var norm = (GEOM.NormalElement)vd.Vertex.FirstOrDefault(e => e is GEOM.NormalElement);
                    if (norm != null)
                    {
                        v.Normal = new[] { norm.X, norm.Y, norm.Z };
                    }


                    var uv = (GEOM.UVElement)vd.Vertex.FirstOrDefault(e => e is GEOM.UVElement);
                    if (uv != null)
                    {
                        v.UV = new[] { new[] { uv.U, uv.V } };
                    }
                    verts.Add(v);
                }
                var facepoints = new List <int>();
                foreach (GEOM.Face face in geom.Faces)
                {
                    facepoints.Add(face.VertexDataIndex0);
                    facepoints.Add(face.VertexDataIndex1);
                    facepoints.Add(face.VertexDataIndex2);
                }

                GeometryModel3D model     = DrawModel(verts.ToArray(), facepoints.ToArray(), mNonSelectedMaterial);
                var             sceneMesh = new SceneGeomMesh(geom, model);
                mGroupMeshes.Children.Add(model);
                mSceneMeshes.Add(sceneMesh);
            }
            foreach (SceneMesh s in mSceneMeshes)
            {
                mMeshListView.Items.Add(s);
            }
            if (mSceneMeshes.Count <= 1)
            {
                MeshesPanel.Visibility = Visibility.Collapsed;
            }
            VertexCount.Text  = String.Format("Vertices: {0}", vertCount);
            PolygonCount.Text = String.Format("Polygons: {0}", polyCount);
        }
コード例 #10
0
        public static meshExpImp.ModelBlocks.Vertex[] Import_VBUF(this StreamReader r, MyProgressBar mpb, int count, VRTF vrtf)
        {
            meshExpImp.ModelBlocks.Vertex[] vertices = new meshExpImp.ModelBlocks.Vertex[count];
            int uvLength = vrtf.Layouts.FindAll(x => x.Usage == VRTF.ElementUsage.UV).Count;

            int line = 0;

            mpb.Init("Import VBUF...", count);
            for (int v = 0; v < count; v++)
            {
                meshExpImp.ModelBlocks.Vertex vertex = new meshExpImp.ModelBlocks.Vertex();
                int nUV = 0;
                vertex.UV = new float[uvLength][];

                foreach (var layout in vrtf.Layouts)
                {
                    string[] split = r.ReadLine().Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
                    if (split.Length < 2)
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has invalid format.", line));
                    int index;
                    if (!int.TryParse(split[0], out index))
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has invalid line index.", line));
                    if (index != v)
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has incorrect line index value {1}.", line, index));
                    byte usage;
                    if (!byte.TryParse(split[1], out usage))
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has invalid Usage.", v));
                    if (usage != (byte)layout.Usage)
                        throw new InvalidDataException(string.Format("'vbuf' line {0} has incorrect line Usage value {1}.", line, usage));

                    switch (usage)
                    {
                        case (byte)VRTF.ElementUsage.Position:
                            vertex.Position = GetFloats(layout.Format, line, split.ConvertAll<Single>(2));
                            break;
                        case (byte)VRTF.ElementUsage.Normal:
                            vertex.Normal = GetFloats(layout.Format, line, split.ConvertAll<Single>(2));
                            break;
                        case (byte)VRTF.ElementUsage.UV:
                            vertex.UV[nUV++] = GetFloats(layout.Format, line, split.ConvertAll<Single>(2));
                            break;
                        case (byte)VRTF.ElementUsage.BlendIndex:
                            byte[] BlendIndices = split.ConvertAll<byte>(2);
                            if (!(BlendIndices.Length == VRTF.ByteSizeFromFormat(layout.Format) || BlendIndices.Length + 1 == VRTF.ByteSizeFromFormat(layout.Format)))
                                throw new InvalidDataException(string.Format("'vbuf' line {0} has incorrect format.", line));
                            vertex.BlendIndices = BlendIndices;
                            break;
                        case (byte)VRTF.ElementUsage.BlendWeight:
                            vertex.BlendWeights = GetFloats(layout.Format, line, split.ConvertAll<Single>(2));
                            break;
                        case (byte)VRTF.ElementUsage.Tangent:
                            vertex.Tangents = GetFloats(layout.Format, line, split.ConvertAll<Single>(2));
                            break;
                        case (byte)VRTF.ElementUsage.Colour:
                            vertex.Color = GetFloats(layout.Format, line, split.ConvertAll<Single>(2));
                            break;
                    }
                    line++;
                }
                vertices[v] = vertex;
                if (nUV != uvLength)
                    throw new InvalidDataException(string.Format("'vbuf' vertex {0} read {1} UV lines, expected {2}.", v, nUV, uvLength));
                mpb.Value++;
            }
            mpb.Done();

            return vertices;
        }