public SceneImportResult LoadSkelletalMesh(string xFile) { this.xFile = xFile; var allocator = new MeshAllocator(); AnimationController aController; FileStream file = new FileStream(xFile, FileMode.Open, FileAccess.Read); GFrame frameRoot = (GFrame)Frame.LoadHierarchyFromX(Engine.Graphics, file, MeshFlags.Managed, allocator, null, out aController); var vd = VertexDescriptor.Get <SkinVertex>(); List <Tuple <Bone, GFrame> > bones = new List <Tuple <Bone, GFrame> >(); Bone root = GetBone(frameRoot, bones); QuadTreeSceneNode sceneNode = new QuadTreeSceneNode(Path.GetFileNameWithoutExtension(xFile), 10); foreach (var item in bones) { if (item.Item2.MeshContainer != null) { var mesh = GetMesh((GMeshContainer)item.Item2.MeshContainer, root, vd); sceneNode.Add(new SkelletalMeshNode(item.Item2.Name, mesh)); } } sceneNode.UpdateLayout(true); try { file.Close(); if (aController != null) { aController.Dispose(); } allocator.DestroyFrame(frameRoot); root.Dispose(); } catch (Exception) { } //AnimationCollection animations = new AnimationCollection(); //animations.Load(xFile, model.RootBone); return(new SceneImportResult { VisualSceneRoot = sceneNode, BoneRoots = new List <Bone> { root } }); }
public EngineContent ToSceneNode() { string name = Path.GetFileNameWithoutExtension(this.name); VertexDescriptor vd = EngineResources.CreateVertexDescriptor <ModelVertex>(); List <Tuple <string, Mesh> > meshes = new List <Tuple <string, Mesh> >(groups.Count); List <SceneNode> nodes = new List <SceneNode>(groups.Count); MeshMaterial[] sceneMaterials = new MeshMaterial[materials.Count]; Dictionary <string, MeshMaterial> materialLookup = new Dictionary <string, MeshMaterial>(); for (int i = 0; i < materials.Values.Count; i++) { var sourceMat = materials.Values[i]; sceneMaterials[i] = new MeshMaterial { Name = name + "_" + sourceMat.Name, Surface = sourceMat.ToSurfaceInfo(), NormalMap = sourceMat.NormalMap, DiffuseMap = sourceMat.Textures != null && sourceMat.Textures.Length > 0 ? sourceMat.Textures[0] : null }; materialLookup.Add(sceneMaterials[i].Name, sceneMaterials[i]); } List <MeshLayer> layers = new List <MeshLayer>(); //register for each positionIndex in the source container the List of the destination vertices that contain that position Dictionary <int, List <VertexInfo> > lookup = new Dictionary <int, List <VertexInfo> >(); VertexInfo vi; ModelVertex v; List <ModelVertex> vertexes = new List <ModelVertex>(); uint[] indexes; #region Groups foreach (var g in groups) { List <MeshMaterial> meshMaterials = new List <MeshMaterial>(); Mesh mesh = new Mesh(vd: vd); mesh.Name = g.Name; indexes = new uint[g.FaceCount * 3]; int k = 0; #region Layers layers.Clear(); foreach (var layer in g.Layers) { int startVertex = int.MaxValue; int vertexCount = 0; MeshLayer meshLayer = new MeshLayer(); meshLayer.startIndex = k; meshLayer.primitiveCount = layer.Faces.Count; var mat = materialLookup[name + "_" + layer.MaterialName]; meshLayer.materialIndex = meshMaterials.IndexOf(mat); if (meshLayer.materialIndex < 0) { meshLayer.materialIndex = meshMaterials.Count; meshMaterials.Add(mat); } #region Faces foreach (var face in layer.Faces) { //for each vertex of the face create a new mesh vertex if the vertex if not yet in the mesh add it to the VertexBuffer //and create a new face in the IndexBuffer for (int i = 0; i < 3; i++) { //vi describe a new vertex vi = new VertexInfo() { PositionIndex = face.Vertexes[i].Position, NormalIndex = -1, TcIndex = -1 }; //if the vertex position is not in the VertexBuffer add it if (!lookup.ContainsKey(vi.PositionIndex)) { v = new ModelVertex(position: positions[vi.PositionIndex]); if ((vertexFormat & VertexFormat.Normal) == VertexFormat.Normal && face.Vertexes[i].Normal >= 0) { vi.NormalIndex = face.Vertexes[i].Normal; v.Normal = normals[vi.NormalIndex]; } if ((vertexFormat & VertexFormat.TexCoord) == VertexFormat.TexCoord && face.Vertexes[i].TexCoord >= 0) { vi.TcIndex = face.Vertexes[i].TexCoord; v.TexCoord = texCoords[vi.TcIndex]; } vi.VertexIndex = vertexes.Count; lookup.Add(vi.PositionIndex, new List <VertexInfo>() { vi }); vertexes.Add(v); vertexCount++; indexes[k] = (uint)vi.VertexIndex; } else { //else get the list of vertices that contains that position and // if new vertex is not in the list create the new destination vertex and add it to the VertexBuffer var vlist = lookup[vi.PositionIndex]; if ((vertexFormat & VertexFormat.Normal) == VertexFormat.Normal) { vi.NormalIndex = face.Vertexes[i].Normal; } if ((vertexFormat & VertexFormat.TexCoord) == VertexFormat.TexCoord) { vi.TcIndex = face.Vertexes[i].TexCoord; } int index = vlist.FindIndex(x => x.Equals(vi)); if (index < 0) { v = new ModelVertex(positions[vi.PositionIndex]); if (vi.NormalIndex >= 0) { v.Normal = normals[vi.NormalIndex]; } if (vi.TcIndex >= 0) { v.TexCoord = texCoords[vi.TcIndex]; } vi.VertexIndex = vertexes.Count; indexes[k] = (uint)vi.VertexIndex; vertexCount++; vertexes.Add(v); vlist.Add(vi); } else { //else the vertex is already in the VertexBuffer so create add the vertex index //to the indexbuffer vi = vlist[index]; indexes[k] = (uint)vi.VertexIndex; } } k++; startVertex = Math.Min(startVertex, vi.VertexIndex); } } #endregion Faces meshLayer.startVertex = startVertex; meshLayer.vertexCount = vertexCount; layers.Add(meshLayer); } #endregion Layers mesh.SetLayers(layers.ToArray()); var data = vertexes.ToArray(); mesh.CreateVertexBuffer(data); if (mesh.VertexCount < ushort.MaxValue) { mesh.CreateIndexBuffer(indexes.Select(x => (ushort)x).ToArray()); } else { mesh.CreateIndexBuffer(indexes); } mesh.DefragmentLayers(); mesh.BlendLayers(); if ((vertexFormat & VertexFormat.Normal) != VertexFormat.Normal) { mesh.ComputeNormals(); } if ((vertexFormat & VertexFormat.TexCoord) != VertexFormat.TexCoord) { mesh.ComputeTextureCoords(CoordMappingType.Spherical); } mesh.ComputeTangents(); nodes.Add(new SceneNode <MeshInstance>(g.Name, new MeshInstance(meshMaterials.ToArray(), mesh))); vertexes.Clear(); //test lookup.Clear(); } #endregion QuadTreeSceneNode node = new QuadTreeSceneNode(name, 10); node.Context = new TechniqueRenderContext(node); foreach (var item in nodes) { node.Add(item); } node.UpdateLayout(); var package = new EngineContent(name); package.Providers.AddRange(sceneMaterials); package.Providers.Add(node); return(package); }