Beispiel #1
0
        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
                }
            });
        }
Beispiel #2
0
        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);
        }