Пример #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
                }
            });
        }
Пример #2
0
        public SceneImportResult LoadStaticMesh(string filename)
        {
            var file                = new FileInfo(filename);
            VertexDescriptor vd     = VertexDescriptor.Get <ModelVertex>();
            List <MeshLayer> layers = new List <MeshLayer>();

            int[] adjacency;
            ExtendedMaterial[] meshMaterials;
            Mesh mesh = new Mesh(vd);
            List <MeshMaterial> material = new List <MeshMaterial>();

            using (SlimDX.Direct3D9.Mesh d3dMesh = SlimDX.Direct3D9.Mesh.FromFile(Engine.Graphics, filename, MeshFlags.Managed))
            {
                adjacency     = d3dMesh.GetAdjacency();
                meshMaterials = d3dMesh.GetMaterials();

                for (int i = 0; i < meshMaterials.Length; i++)
                {
                    var    matd3d          = meshMaterials[i].MaterialD3D;
                    string textureFilename = meshMaterials[i].TextureFileName;
                    if (textureFilename != null && !Path.IsPathRooted(textureFilename))
                    {
                        textureFilename = Path.Combine(Path.GetDirectoryName(filename), textureFilename);
                    }
                    material.Add(new MeshMaterial()
                    {
                        Name          = file.Name + "_material" + i,
                        Alpha         = matd3d.Diffuse.Alpha,
                        Diffuse       = matd3d.Diffuse.ToVector3(),
                        Specular      = matd3d.Specular.ToVector3(),
                        SpecularPower = Math.Max(1, matd3d.Power),
                        Reflectivity  = 0,
                        Refractitity  = 0,
                        EmissiveColor = matd3d.Emissive.ToVector3(),
                        DiffuseMap    = textureFilename != null && File.Exists(textureFilename) ?
                                        textureFilename : null
                    });
                }

                ModelVertex[] vertexes = new ModelVertex[d3dMesh.VertexCount];
                Array         indices;

                if (d3dMesh.IndexBuffer.Description.Format == Format.Index16)
                {
                    indices = new ushort[d3dMesh.FaceCount * 3];
                }
                else
                {
                    indices = new uint[d3dMesh.FaceCount * 3];
                }

                DataStream       vertexStream = d3dMesh.LockVertexBuffer(0);
                VertexDescriptor meshVD       = new VertexDescriptor(d3dMesh.GetDeclaration());
                int    positionOffset         = meshVD.GetOffset(DeclarationUsage.Position, 0);
                int    normalOffset           = meshVD.GetOffset(DeclarationUsage.Normal, 0);
                int    texCoordOffset         = meshVD.GetOffset(DeclarationUsage.TextureCoordinate, 0);
                byte[] buffer;
                unsafe
                {
                    buffer = new byte[vertexStream.Length];
                    vertexStream.Read(buffer, 0, (int)vertexStream.Length);
                    fixed(byte *_pter = buffer)
                    {
                        byte *pter = _pter;

                        for (int i = 0; i < d3dMesh.VertexCount; i++)
                        {
                            vertexes[i].Position = *((Vector3 *)(pter + positionOffset));
                            if (normalOffset > 0)
                            {
                                vertexes[i].Normal = *((Vector3 *)(pter + normalOffset));
                            }
                            if (texCoordOffset > 0)
                            {
                                vertexes[i].TexCoord = *((Vector2 *)(pter + texCoordOffset));
                            }

                            pter += d3dMesh.BytesPerVertex;
                        }
                    }

                    d3dMesh.UnlockVertexBuffer();

                    DataStream indexStream = d3dMesh.LockIndexBuffer(0);
                    GCHandle   handler     = GCHandle.Alloc(indices, GCHandleType.Pinned);
                    byte *     indexPter   = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(indices, 0);

                    buffer = new byte[indexStream.Length];
                    indexStream.Read(buffer, 0, (int)indexStream.Length);
                    for (int i = 0; i < indexStream.Length; i++)
                    {
                        indexPter[i] = buffer[i];
                    }
                    handler.Free();
                    d3dMesh.UnlockIndexBuffer();
                }

                mesh.CreateVertexBuffer(vertexes);
                if (d3dMesh.IndexBuffer.Description.Format == Format.Index16)
                {
                    mesh.CreateIndexBuffer((ushort[])indices);
                }
                else
                {
                    mesh.CreateIndexBuffer((uint[])indices);
                }

                var d3dComponents = d3dMesh.GetAttributeTable();
                if (d3dComponents == null)
                {
                    MeshLayer component = new MeshLayer();
                    layers.Add(component);
                    material.Add(MeshMaterial.CreateDefaultMaterial(file.Name + "_default"));

                    component.materialIndex  = 0;
                    component.primitiveCount = mesh.FaceCount;
                    component.startIndex     = 0;
                    component.startVertex    = 0;
                    component.vertexCount    = mesh.VertexCount;
                }
                else
                {
                    for (int i = 0; i < d3dComponents.Length; i++)
                    {
                        AttributeRange ar = d3dComponents[i];

                        MeshLayer component = new MeshLayer();
                        layers.Add(component);

                        component.materialIndex  = ar.AttribId;
                        component.primitiveCount = ar.FaceCount;
                        component.startIndex     = ar.FaceStart * 3;
                        component.startVertex    = ar.VertexStart;
                        component.vertexCount    = ar.VertexCount;
                    }
                }

                mesh.Materials = material.ToArray();
                mesh.SetLayers(layers.ToArray());

                if (normalOffset < 0)
                {
                    mesh.ComputeNormals();
                }
                if (texCoordOffset < 0)
                {
                    mesh.ComputeTextureCoords(CoordMappingType.Spherical);
                }

                mesh.ComputeTangents();

                meshVD.Dispose();
            }

            StaticMeshSceneNode meshNode = new StaticMeshSceneNode(file.Name, mesh);

            return(new SceneImportResult {
                VisualSceneRoot = meshNode, VisualMaterials = material
            });
        }