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)); }
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; }
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); }
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; }
public bool SetVertices(MLOD mlod, int meshIndex, VRTF vrtf, Vertex[] vertices, float[] uvscales) { return SetVertices(mlod, mlod.Meshes[meshIndex], vrtf, vertices, uvscales); }
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; }
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); }
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(); }
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); }
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; }