예제 #1
0
        public ContentItem LoadContentItem(string filename,
                                           IContentImporter importer              = null,
                                           IContentProcessor processor            = null,
                                           Dictionary <string, object> opaqueData = null)
        {
            if (opaqueData == null)
            {
                opaqueData = new Dictionary <string, object>();
            }
            if (importer == null)
            {
                importer = CreateImporter(FindImporterByExtension(Path.GetExtension(filename)), opaqueData);
            }
            if (processor == null)
            {
                processor = CreateProcessor(FindDefaultProcessor(importer.GetType()), opaqueData);
            }

            object item;

            using (FileStream stream = File.OpenRead(filename))
            {
                item = importer.Import(stream, this);
            }
            _processorContext.PushDirectory(Path.GetDirectoryName(filename));
            item = processor.Process(item, _processorContext);
            _processorContext.PopDirectory();

            return((ContentItem)item);
        }
예제 #2
0
 public static T Load <T>(this IContentImporter loader, string fileName, IServiceProvider serviceProvider) where T : class
 {
     using (var stream = File.OpenRead(fileName))
     {
         return(loader.Import(stream, serviceProvider) as T);
     }
 }
 public DefaultContentImporterInterceptor(IContentImporter defaultContentImporter
                                          , IPropertyImporter propertyImporter
                                          , IContentRepository contentRepository
                                          , ContentLanguageSettingRepository contentLanguageSettingRepository
                                          , IPermanentLinkMapper permanentLinkMapper
                                          , IContentProviderManager contentProviderManager
                                          , IContentCacheRemover contentCacheRemover
                                          , IContentCacheListingRemover contentCacheListingRemover
                                          , IPageQuickSearch pageQuickSearch
                                          , IContentTypeRepository contentTypeRepository
                                          , IDynamicPropertiesLoader dynamicPropertiesLoader)
     : base(propertyImporter, contentRepository, contentLanguageSettingRepository
            , permanentLinkMapper, contentProviderManager, contentCacheRemover
            , contentCacheListingRemover, pageQuickSearch, contentTypeRepository
            , dynamicPropertiesLoader)
 {
     this.defaultContentImporter           = defaultContentImporter;
     this.propertyImporter                 = propertyImporter;
     this.contentRepository                = contentRepository;
     this.contentLanguageSettingRepository = contentLanguageSettingRepository;
     this.permanentLinkMapper              = permanentLinkMapper;
     this.contentProviderManager           = contentProviderManager;
     this.contentCacheRemover              = contentCacheRemover;
     this.contentCacheListingRemover       = contentCacheListingRemover;
     this.pageQuickSearch         = pageQuickSearch;
     this.contentTypeRepository   = contentTypeRepository;
     this.dynamicPropertiesLoader = dynamicPropertiesLoader;
 }
예제 #4
0
            /// <summary>
            /// Initializes a new instance of the <see cref="RegistryEntry"/> structure.
            /// </summary>
            /// <param name="importer">The registered importer instance.</param>
            public RegistryEntry(IContentImporter importer)
            {
                Contract.Require(importer, nameof(importer));

                var baseImporterType = ContentImporterRegistry.GetBaseContentImporterType(importer.GetType());
                var outputType       = baseImporterType.GetGenericArguments().Single();

                this.importer   = importer;
                this.outputType = outputType;
            }
            /// <summary>
            /// Initializes a new instance of the <see cref="RegistryEntry"/> structure.
            /// </summary>
            /// <param name="importer">The registered importer instance.</param>
            public RegistryEntry(IContentImporter importer)
            {
                Contract.Require(importer, nameof(importer));

                var baseImporterType = ContentImporterRegistry.GetBaseContentImporterType(importer.GetType());
                var outputType = baseImporterType.GetGenericArguments().Single();

                this.importer = importer;
                this.outputType = outputType;
            }
예제 #6
0
        static void Main(string[] args)
        {
            log4net.Config.BasicConfigurator.Configure(new log4net.Appender.DebugAppender());

            _opaqueData["TextureType"] = TextureType.Texture2D;
            if (!ParseCommandLine(args))
            {
                return;
            }

            if (string.IsNullOrEmpty(_outputName))
            {
                _outputName = string.Format("{0}.meb", Path.GetFileNameWithoutExtension(_imageName));
            }



            //GetTypeWriters();
            ProcessAssemblies();

            string ext = Path.GetExtension(_imageName).ToLower();
            var    imp = _importers.FirstOrDefault(i => i.attribue.FileExtensions.Contains(ext));

            if (imp.type == null)
            {
                Console.WriteLine("file format is not handled by TextureImporter.");
                return;
            }

            ContentManager           manager = new ContentManager(_log);
            ContentTypeWriterManager contentTypeWriterManager = new ContentTypeWriterManager();

            contentTypeWriterManager.RegisterTypeWriter <Texture2DContent>(new Texture2DWriter());

            IContentImporter importer = CreateImporter(imp.type, _opaqueData);

            var content = importer.Import(_imageName, manager);

            IContentProcessor processor = CreateProcessor(FindDefaultProcessor(importer.GetType()), _opaqueData);

            object processedContent = processor.Process(content, new ContentProcessorContext());

            ContentTypeWriter typeWriter = GetTypeWriter(processedContent.GetType());

            using (FileStream stream = new FileStream(_outputName, FileMode.OpenOrCreate))
            {
                ContentWriter writer = manager.CreateWriter(contentTypeWriterManager, stream);
                writer.WriteObject(processedContent, typeWriter);
                writer.Flush();
            }
        }
예제 #7
0
        static TextureContent GetMaterialTexture(Property property, IContentImporter importer, string modelFilename)
        {
            foreach (var srcobj in property.SrcObjects)
            {
                var tex = srcobj as Texture;
                if (tex != null)
                {
                    var textureFilename = Path.Combine(Path.GetDirectoryName(modelFilename), tex.Filename);

                    return(importer.ImportTexture2D(textureFilename, importer));
                }
            }

            return(null);
        }
예제 #8
0
        private bool FindStreamInternal(string fileName, out Stream stream, out IContentImporter loader)
        {
            var resolverCount = resolvers.Count;

            for (int i = 0; i < resolverCount; i++)
            {
                if (resolvers[i].TryResolveContent(fileName, this, out stream, out loader))
                {
                    return(true);
                }
            }
            stream = null;
            loader = null;
            return(false);
        }
예제 #9
0
        private bool FindStream(string fileName, out Stream stream, out IContentImporter loader)
        {
            var searchDirectoryCount = searchDirectories.Count;

            for (int i = 0; i < searchDirectoryCount; i++)
            {
                var searchDirectory = string.IsNullOrEmpty(searchDirectories[i])
                    ? Directory.GetCurrentDirectory() : Path.GetFullPath(searchDirectories[i]);
                CurrentFileName = Path.Combine(searchDirectory, fileName);
                if (FindStreamInternal(CurrentFileName, out stream, out loader))
                {
                    return(true);
                }
            }
            stream = null;
            loader = null;
            return(false);
        }
예제 #10
0
        public override bool Execute()
        {
            Log.LogMessage("Building content:");

            XBuildLogger    logger   = new XBuildLogger(this.Log);
            ContentCompiler compiler = new ContentCompiler(PipelineAssemblies);

            foreach (ITaskItem sourceItem in SourceAssets)
            {
                //foreach (string name in sourceItem.MetadataNames)
                //	Log.LogMessage(name + " : " + sourceItem.GetMetadata(name));
                string assetName = sourceItem.GetMetadata("Name");

                Log.LogMessage("Building " + assetName);

                Stream        outputStream  = new FileStream(OutputDirectory + assetName + ".xnb", FileMode.OpenOrCreate);
                ContentWriter contentWriter = new ContentWriter(outputStream, getTargetPlatform(), CompressContent);

                string importerName  = sourceItem.GetMetadata("Importer");
                string processorName = sourceItem.GetMetadata("Processor");

                IContentImporter importer = getImporterInstance(importerName);
                if (importer == null)
                {
                    Log.LogError("Could not find the importer (" + importerName + ")");
                }

                IContentProcessor processor = getProcessorInstance(processorName);
                if (importer == null)
                {
                    Log.LogError("Could not find the processor (" + processorName + ")");
                }

                Log.LogMessage("Using " + importerName + " and " + processorName);

                ContentImporterContext  importerContext  = new ContentImporterContext(this, IntermediateDirectory, OutputDirectory, logger);
                ContentProcessorContext processorContext = new ContentProcessorContext();

                processor.Process(importer.Import(sourceItem.GetMetadata("Include"), importerContext), processorContext);
            }

            return(true);
        }
 public DefaultDataImporterInterceptor(IDataImporter defaultDataImporter
                                       , IContentCacheRemover contentCacheRemover
                                       , IPrincipalAccessor principalAccessor
                                       , IDataImportEvents dataImportEvents
                                       , IDataImportEventsRaiser dataImportEventsRaiser
                                       , IContentRepository contentRepository
                                       , IPermanentLinkMapper permanentLinkMapper
                                       , IContentTypeRepository contentTypeRepository
                                       , ContentTypeAvailabilityService contentTypeAvailabilityService
                                       , IAvailableSettingsRepository availableSettingsRepository
                                       , IContentImporter contentImporter
                                       , IContentTransferValidator contentTransferValidator
                                       , PropertyCategoryTransform propertyCategoryTransform
                                       , ContentRootRepository contentRootRepository
                                       , ISiteDefinitionRepository siteDefinitionRepository
                                       , ContentOptions contentOptions
                                       , ISiteDefinitionResolver siteDefinitionResolver)
     : base(contentCacheRemover, principalAccessor, dataImportEvents
            , dataImportEventsRaiser, contentRepository
            , permanentLinkMapper, contentTypeRepository
            , contentTypeAvailabilityService, availableSettingsRepository
            , contentImporter, contentTransferValidator
            , propertyCategoryTransform, contentRootRepository
            , siteDefinitionRepository, contentOptions, siteDefinitionResolver)
 {
     this.defaultDataImporter            = defaultDataImporter;
     this.contentCacheRemover            = contentCacheRemover;
     this.principalAccessor              = principalAccessor;
     this.dataImportEvents               = dataImportEvents;
     this.dataImportEventsRaiser         = dataImportEventsRaiser;
     this.contentRepository              = contentRepository;
     this.permanentLinkMapper            = permanentLinkMapper;
     this.contentTypeRepository          = contentTypeRepository;
     this.contentTypeAvailabilityService = contentTypeAvailabilityService;
     this.availableSettingsRepository    = availableSettingsRepository;
     this.contentImporter           = contentImporter;
     this.contentTransferValidator  = contentTransferValidator;
     this.propertyCategoryTransform = propertyCategoryTransform;
     this.contentRootRepository     = contentRootRepository;
     this.siteDefinitionRepository  = siteDefinitionRepository;
     this.contentOptions            = contentOptions;
     this.siteDefinitionResolver    = siteDefinitionResolver;
 }
예제 #12
0
        public FileSystemResolver()
        {
            foreach (var importer in Extensions.FindImplementations <IContentImporter>())
            {
                var supportedFileExtensions = importer.SupportedFileExtensions;
                if (supportedFileExtensions == null)
                {
                    continue;
                }

                foreach (var ext in supportedFileExtensions)
                {
                    IContentImporter existingImporter = null;
                    if (importers.TryGetValue(ext, out existingImporter))
                    {
                        throw new InvalidOperationException(string.Format("{0} conflicts with {1}", importer, existingImporter));
                    }
                    importers.Add(ext, importer);
                }
            }
        }
예제 #13
0
        static MaterialContent GetMaterialFromMaterial(SurfaceMaterial material, ShaderContent vertexShaderStage, ShaderContent fragmentShaderStage, IContentImporter importer, string filename)
        {
            var shaderTuple = new Tuple <ShaderContent, ShaderContent>(vertexShaderStage, fragmentShaderStage);

            if (_materialsCache.ContainsKey(material) && _materialsCache[material].ContainsKey(shaderTuple))
            {
                return(_materialsCache[material][shaderTuple]);
            }

            if (!_materialsCache.ContainsKey(material))
            {
                _materialsCache[material] = new Dictionary <Tuple <ShaderContent, ShaderContent>, MaterialContent>();
            }

            var material2 = new MaterialContent();

            material2.VertexShader   = vertexShaderStage;
            material2.FragmentShader = fragmentShaderStage;
            material2.Alpha          = 1;
            material2.DiffuseColor   = new Vector3(0.5f, 0.5f, 0.5f);
            material2.Name           = material.Name;

            Property diffuseProp;
            Property emissiveProp;
            Property textureProp;

            if (material is SurfaceLambert)
            {
                var lambert = material as SurfaceLambert;
                diffuseProp  = GetMaterialColorProperty(lambert, "Diffuse", lambert.Diffuse);
                emissiveProp = GetMaterialColorProperty(lambert, "Emissive", lambert.Emissive);
                textureProp  = FindTextureProperty(lambert, "Diffuse", lambert.Diffuse);
            }
            else
            {
                diffuseProp  = GetMaterialColorProperty(material, "Diffuse");
                emissiveProp = GetMaterialColorProperty(material, "Emissive");
                textureProp  = FindTextureProperty(material, "Diffuse");
            }

            if (diffuseProp != null)
            {
                material2.DiffuseColor = GetPropertyValue(diffuseProp);
            }
            if (emissiveProp != null)
            {
                material2.EmissiveColor = GetPropertyValue(emissiveProp);
            }
            if (textureProp != null)
            {
                var tex = GetMaterialTexture(textureProp, importer, filename);
                if (tex != null)
                {
                    material2.Texture = tex;
                }
            }

            if (material is SurfacePhong)
            {
                var phong = material as SurfacePhong;

                var specularProp = GetMaterialColorProperty(phong, "Specular", phong.Specular);
                if (specularProp != null)
                {
                    material2.SpecularColor = GetPropertyValue(specularProp);

                    var props =
                        phong.FindProperties(
                            p => p.Name.ToLower() == "shininessexponent" ||
                            p.Name.ToLower() == "shininess");
                    double shininess = 0;
                    foreach (var prop in props)
                    {
                        if (prop.PropertyDataType == typeof(double))
                        {
                            shininess = prop.Get <double>();
                            if (shininess > 0)
                            {
                                break;
                            }
                        }
                    }

                    material2.SpecularPower = (float)shininess;
                }
            }

            if (material is SurfaceLambert)
            {
                var transparencyFactor = (material as SurfaceLambert).TransparencyFactor;
                if (transparencyFactor != null)
                {
                    material2.Alpha = (float)(1 - transparencyFactor.Get());
                }
            }

            _materialsCache[material][shaderTuple] = material2;

            return(material2);
        }
예제 #14
0
        public ModelContent ImportModel(string filename, IContentImporter importer)
        {
            if (File.Exists(filename))
            {
            }
            else if (File.Exists(filename + ".fbx"))
            {
                filename += ".fbx";
            }
            else if (next != null)
            {
                return(next(filename, importer));
            }
            else
            {
                throw new FileNotFoundException("The file could not be found", filename);
            }

            var fimporter = new Importer();

            var scene = fimporter.Import(filename);



            var model = new ModelContent();

            model.Filename = filename;


            var bonesByNode = new Dictionary <Node, BoneContent>();
            var nodesByBone = new Dictionary <BoneContent, Node>();

            foreach (var node in scene.Nodes)
            {
                var bone = BoneFromNode(node);
                bonesByNode[node] = bone;
                nodesByBone[bone] = node;
                model.Bones.Add(bone);
                if (node == scene.GetRootNode())
                {
                    model.RootBoneIndex = model.Bones.Count - 1;
                    bone.Transform      = bone.Transform.Transposed();
                }
            }
            foreach (var node in scene.Nodes)
            {
                var bone = bonesByNode[node];

                if (node.GetNodeAttributeCount() > 0 &&
                    node.GetNodeAttributeByIndex(0) is Mesh)
                {
                    var mesh  = (Mesh)node.GetNodeAttributeByIndex(0);
                    var mesh2 = new MeshContent();
                    model.Meshes.Add(mesh2);
                    mesh2.ParentBone = bone;
                    mesh2.Name       = mesh.GetName();

                    bool          isSkinned = true;
                    ShaderContent vert;
                    if (mesh.GetDeformerCount() < 1)
                    {
                        isSkinned = false;
                        vert      = importer.ImportShaderStage("$basic", ShaderType.Vertex, importer);
                    }
                    else if (mesh.GetDeformerCount() > 1)
                    {
                        throw new NotImplementedException();
                    }
                    else
                    {
                        vert = importer.ImportShaderStage("$skinned", ShaderType.Vertex, importer);
                    }
                    var frag = importer.ImportShaderStage("$basic", ShaderType.Fragment, importer);

                    // calculate the global transform for the mesh

                    var meshTransform = node.EvaluateGlobalTransform();

                    // extract the vertex postions

                    var vertices =
                        Enumerable.Range(0, mesh.GetControlPointsCount())
                        .Select(ix => {
                        var cp    = mesh.GetControlPointAt((int)ix);
                        var baked = meshTransform.MultNormalize(cp);
                        var pos   = baked.ToChamber().ToVectorXYZ();
                        return(new Vertex_PBiBwNT {
                            Position = pos
                        });
                    })
                        .ToList();

                    // extract the blend indices and weights

                    if (mesh.GetDeformerCount() == 1)
                    {
                        if (!(mesh.GetDeformer(0) is Skin))
                        {
                            throw new NotImplementedException("Only Skin deformers are implemented");
                        }

                        var boneIndicesL =
                            Enumerable.Range(
                                0,
                                mesh.GetControlPointsCount())
                            .Select(x => new List <float>())
                            .ToList();
                        var boneWeightsL =
                            Enumerable.Range(
                                0,
                                mesh.GetControlPointsCount())
                            .Select(x => new List <float>())
                            .ToList();

                        int i;

                        var skin = (Skin)mesh.GetDeformer(0);
                        foreach (var cluster in skin.Clusters)
                        {
                            var cnode     = cluster.GetLink();
                            var cbone     = bonesByNode[cnode];
                            var boneIndex = model.Bones.IndexOf(cbone);

                            for (i = 0; i < cluster.ControlPointIndices.Count; i++)
                            {
                                var index  = cluster.ControlPointIndices[i];
                                var weight = cluster.ControlPointWeights[i];

                                if (boneIndicesL[index].Count > 4 ||
                                    boneWeightsL[index].Count > 4)
                                {
                                    throw new NotImplementedException("Too many indices or weights");
                                }

                                boneIndicesL[index].Add((float)boneIndex);
                                boneWeightsL[index].Add((float)weight);

                                if (boneIndicesL[index].Count > 4 ||
                                    boneWeightsL[index].Count > 4)
                                {
                                    throw new NotImplementedException("Too many indices or weights");
                                }
                            }
                        }

                        Func <List <float>, Vector4> convert = fs => {
                            if (fs.Count == 4)
                            {
                                return(new Vector4(fs[0], fs[1], fs[2], fs[3]));
                            }
                            if (fs.Count == 3)
                            {
                                return(new Vector4(fs[0], fs[1], fs[2], 0));
                            }
                            if (fs.Count == 2)
                            {
                                return(new Vector4(fs[0], fs[1], 0, 0));
                            }
                            if (fs.Count == 1)
                            {
                                return(new Vector4(fs[0], 0, 0, 0));
                            }
                            return(Vector4.Zero);
                        };

                        var boneIndicesV = boneIndicesL.Select(convert).ToList();
                        var boneWeightsV = boneWeightsL.Select(convert).ToList();

                        for (i = 0; i < vertices.Count; i++)
                        {
                            var vertex = vertices[i];
                            vertex.SetBlendIndices(boneIndicesV[i]);
                            vertex.SetBlendWeights(boneWeightsV[i]);
                            vertices[i] = vertex;
                        }
                    }


                    // construct a list of polygons
                    //  beyond this point, we don't need `vertices` until it
                    //  gets re-used to build the vertex buffer

                    var polygons = mesh.PolygonIndexes.Select(p =>
                                                              new PolygonBuilder {
                        PolygonVertexIndexes = p,
                        Vertexes             = p.Select(ix => vertices[(int)ix]).ToList(),
                    }).ToList();

                    var polygonsByMaterial = new Dictionary <SurfaceMaterial, List <PolygonBuilder> >();

                    // organize the mesh's polygons by material

                    var layer      = mesh.GetLayer(0);
                    var matelem    = layer.GetMaterials();
                    var matindexes = matelem.MaterialIndexes.List;// GetIndexArray().List;
                    if (matelem.ReferenceMode != LayerElement.EReferenceMode.IndexToDirect)
                    {
                        throw new NotImplementedException("A materials must have a reference mode of IndexToDirect");
                    }
                    if (matelem.MappingMode == LayerElement.EMappingMode.AllSame)
                    {
                        // only one material
                        var material = node.GetMaterial(matindexes[0]);

                        polygonsByMaterial[material] = new List <PolygonBuilder>(polygons);
                    }
                    else if (matelem.MappingMode == LayerElement.EMappingMode.ByPolygon)
                    {
                        // multiple materials
                        foreach (var mat in node.Materials)
                        {
                            polygonsByMaterial[mat] = new List <PolygonBuilder>();
                        }
                        int i;
                        for (i = 0; i < matindexes.Count; i++)
                        {
                            var mat = node.Materials[matindexes[i]];
                            polygonsByMaterial[mat].Add(polygons[i]);
                        }
                    }
                    else
                    {
                        throw new NotImplementedException("Materials must have mapping modes of AllSame or ByPolygon");
                    }

                    // extract the vertex normals

                    if (layer.GetNormals() != null)
                    {
                        var normalElement = layer.GetNormals();
                        if (normalElement.MappingMode != LayerElement.EMappingMode.ByPolygonVertex)
                        {
                            throw new NotImplementedException("Normals layer elements must have a mapping mode of ByPolygonVertex");
                        }
                        if (normalElement.ReferenceMode != LayerElement.EReferenceMode.Direct &&
                            normalElement.ReferenceMode != LayerElement.EReferenceMode.IndexToDirect)
                        {
                            throw new NotImplementedException("Normals layer elements must have a reference mode of Direct or IndexToDirect");
                        }
                        int k = 0;
                        foreach (var poly in polygons)
                        {
                            int i;
                            for (i = 0; i < poly.Vertexes.Count; i++)
                            {
                                int nindex;
                                if (normalElement.ReferenceMode == LayerElement.EReferenceMode.Direct)
                                {
                                    nindex = k;
                                }
                                else
                                {
                                    nindex = normalElement.GetIndexArray().GetAt(k);
                                }

                                var v      = normalElement.GetDirectArray().GetAt(nindex);
                                var vertex = poly.Vertexes[i];
                                vertex.Normal    = meshTransform.MultNormalize(v).ToChamber().ToVectorXYZ();
                                poly.Vertexes[i] = vertex;
                                k++;
                            }
                        }
                    }

                    // extract the texture coordinates

                    if (layer.GetUVs() != null)
                    {
                        var uvElement = layer.GetUVs();
                        if (uvElement.MappingMode != LayerElement.EMappingMode.ByPolygonVertex)
                        {
                            throw new NotImplementedException("UV layer elements must have a mapping mode of ByPolygonVertex");
                        }
                        if (uvElement.ReferenceMode != LayerElement.EReferenceMode.Direct &&
                            uvElement.ReferenceMode != LayerElement.EReferenceMode.IndexToDirect)
                        {
                            throw new NotImplementedException("UV layer elements must have a reference mode of Direct or IndexToDirect");
                        }
                        int k = 0;
                        foreach (var poly in polygons)
                        {
                            int i;
                            for (i = 0; i < poly.Vertexes.Count; i++)
                            {
                                int nindex;
                                if (uvElement.ReferenceMode == LayerElement.EReferenceMode.Direct)
                                {
                                    nindex = k;
                                }
                                else
                                {
                                    nindex = uvElement.GetIndexArray().GetAt(k);
                                }

                                var v      = uvElement.GetDirectArray().GetAt(nindex);
                                var vv     = v.ToChamber();
                                var vertex = poly.Vertexes[i];
                                vertex.SetTextureCoords(new ChamberLib.Vector2(vv.X, 1 - vv.Y));
                                poly.Vertexes[i] = vertex;
                                k++;
                            }
                        }
                    }

                    // trianglize polygons with more than three points

                    foreach (var mat in polygonsByMaterial.Keys.ToArray())
                    {
                        var polys = polygonsByMaterial[mat];
                        polygonsByMaterial[mat] = polys.SelectMany(p => {
                            if (p.Vertexes.Count < 3)
                            {
                                throw new InvalidOperationException();
                            }
                            if (p.Vertexes.Count == 3)
                            {
                                return(p.Yield());
                            }
                            int i;
                            var newPolys = new List <PolygonBuilder>();
                            for (i = 2; i < p.Vertexes.Count; i++)
                            {
                                var pb = new PolygonBuilder();

                                pb.PolygonVertexIndexes = new List <long>();
                                pb.PolygonVertexIndexes.Add(p.PolygonVertexIndexes[0]);
                                pb.PolygonVertexIndexes.Add(p.PolygonVertexIndexes[i - 1]);
                                pb.PolygonVertexIndexes.Add(p.PolygonVertexIndexes[i]);

                                pb.Vertexes = new List <Vertex_PBiBwNT>();
                                pb.Vertexes.Add(p.Vertexes[0]);
                                pb.Vertexes.Add(p.Vertexes[i - 1]);
                                pb.Vertexes.Add(p.Vertexes[i]);

                                newPolys.Add(pb);
                            }
                            return(newPolys);
                        }).ToList();
                    }

                    // construct the vertex and index buffers

                    var vertset = new HashSet <Vertex_PBiBwNT>();
                    vertices.Clear();
                    var indices = new List <int>();

                    var vertexBuffer = new VertexBufferContent();
                    var indexBuffer  = new IndexBufferContent();

                    model.VertexBuffers.Add(vertexBuffer);
                    model.IndexBuffers.Add(indexBuffer);

                    var indexByVertex = new Dictionary <Vertex_PBiBwNT, int>();

                    foreach (var mat in polygonsByMaterial.Keys)
                    {
                        var polys     = polygonsByMaterial[mat];
                        var polyverts = polys.SelectMany(p => p.Vertexes).ToArray();

                        var startIndex = indices.Count;

                        int n0 = vertices.Count;
                        vertices.AddRange(polyverts.Except(vertset));
                        int n1 = vertices.Count;
                        int i;
                        for (i = n0; i < n1; i++)
                        {
                            indexByVertex[vertices[i]] = i;
                        }

                        var polyindices = polyverts.Select(p => indexByVertex[p]);
                        indices.AddRange(polyindices);

                        vertset.AddRange(polyverts);

                        mesh2.Parts.Add(new PartContent()
                        {
                            Material       = GetMaterialFromMaterial(mat, vert, frag, importer, filename),
                            StartIndex     = startIndex,
                            PrimitiveCount = polys.Count,
                            Vertexes       = vertexBuffer,
                            Indexes        = indexBuffer,
                        });
                    }

                    indexBuffer.Indexes = indices.Select(ix => (short)ix).ToArray();

                    if (isSkinned)
                    {
                        vertexBuffer.Vertices = vertices.Cast <IVertex>().ToArray();
                    }
                    else
                    {
                        vertexBuffer.Vertices =
                            vertices.Select <Vertex_PBiBwNT, IVertex>(v =>
                                                                      new Vertex_PNT {
                            Position      = v.Position,
                            Normal        = v.Normal,
                            TextureCoords = v.TextureCoords,
                        }).ToArray();
                    }
                }
            }
            foreach (var node in scene.Nodes)
            {
                var bone = bonesByNode[node];
                int i;
                int n = node.GetChildCount();
                for (i = 0; i < n; i++)
                {
                    bone.ChildBoneIndexes.Add(scene.Nodes.IndexOf(node.GetChild(i)));
                }
            }

            if (scene.Poses.Count > 0)
            {
                var pose = scene.Poses[0];
                foreach (var pi in pose.PoseInfos)
                {
                    var bone = bonesByNode[pi.Node];
                    var m    = pi.Matrix.ToChamber();
                    bone.Transform = m;
                }
            }

            // animations

            Dictionary <string, AnimationSequence> sequences = null;
            var numstacks = scene.GetSrcObjectCount <AnimStack>();
            int j;

            for (j = 0; j < numstacks; j++)
            {
                var stack = scene.GetSrcObject <AnimStack>(j);

                if (sequences == null)
                {
                    sequences = new Dictionary <string, AnimationSequence>();
                }

                var timespan = stack.GetLocalTimeSpan();
                var layer    = (AnimLayer)stack.SrcObjects.FirstOrDefault(x => x is AnimLayer);

                scene.SetCurrentAnimationStack(stack);
                var        eval   = scene.GetAnimationEvaluator();
                var        frames = new List <AnimationFrame>();
                FbxTime    t;
                int        i;
                var        startOffset     = timespan.Start.GetSecondDouble();
                const int  framesPerSecond = 60;
                const long timeStep        = FbxTime.UnitsPerSecond / framesPerSecond;
                for (t = timespan.Start; t.Value <= timespan.Stop.Value; t = new FbxTime(t.Value + timeStep))
                {
                    var transforms = new ChamberLib.Matrix[model.Bones.Count];
                    for (i = 0; i < model.Bones.Count; i++)
                    {
                        var node = nodesByBone[model.Bones[i]];
                        var m    = eval.GetNodeLocalTransform(node, t).ToChamber();

                        transforms[i] = m;
                    }
                    frames.Add(new AnimationFrame((float)(t.GetSecondDouble() - startOffset), transforms));
                }

                var name = stack.Name.Replace("AnimStack::", "");
                sequences.Add(
                    name,
                    new AnimationSequence(
                        (float)(timespan.Stop.GetSecondDouble() - timespan.Start.GetSecondDouble()),
                        frames.ToArray(),
                        name));
            }

            Matrix[]   localTransforms    = null;
            Matrix[]   absoluteTransforms = null;
            List <int> skeletonHierarchy  = null;

            if (model.Bones != null && model.Bones.Count > 0)
            {
                skeletonHierarchy = Enumerable.Repeat(-1, model.Bones.Count).ToList();
                int i;
                for (i = 0; i < model.Bones.Count; i++)
                {
                    foreach (var childIndex in model.Bones[i].ChildBoneIndexes)
                    {
                        skeletonHierarchy[childIndex] = i;
                    }
                }
                localTransforms = new Matrix[model.Bones.Count];
                var globalTransforms = model.Bones.Select(b => b.Transform).ToArray();
                for (i = 0; i < model.Bones.Count; i++)
                {
                    var p = skeletonHierarchy[i];
                    if (p < 0)
                    {
                        localTransforms[i] = globalTransforms[i];
                    }
                    else
                    {
                        localTransforms[i] = globalTransforms[i] * globalTransforms[p].Inverted();
                    }
                }

                absoluteTransforms = new Matrix[model.Bones.Count];
                for (i = 0; i < model.Bones.Count; i++)
                {
                    absoluteTransforms[i] = globalTransforms[i].Inverted();
                }
            }

            if (sequences != null ||
                localTransforms != null ||
                absoluteTransforms != null ||
                skeletonHierarchy != null)
            {
                if (sequences == null)
                {
                    sequences = new Dictionary <string, AnimationSequence>();
                }
                if (localTransforms == null)
                {
                    localTransforms = new Matrix[0];
                }
                if (absoluteTransforms == null)
                {
                    absoluteTransforms = new Matrix[0];
                }
                if (skeletonHierarchy == null)
                {
                    skeletonHierarchy = new List <int>();
                }

                model.AnimationData =
                    new AnimationData(
                        sequences,
                        localTransforms.ToList(),
                        absoluteTransforms.ToList(),
                        skeletonHierarchy);
            }

            return(model);
        }
예제 #15
0
        public bool TryResolveContent(string fileName, IServiceProvider serviceProvider, out Stream stream, out IContentImporter contentImporter)
        {
            ZipArchive      package;
            ZipArchiveEntry entry;
            string          packageFilename;
            string          packageDirectory = fileName;

            while (!string.IsNullOrEmpty(packageDirectory = Path.GetDirectoryName(packageDirectory)))
            {
                if (!cachedPackages.TryGetValue(packageDirectory, out package))
                {
                    cachedPackages[packageDirectory] = package =
                        Directory.Exists(packageDirectory) &&
                        File.Exists(packageFilename = packageDirectory + FileExtension) ?
                        new ZipArchive(File.OpenRead(packageFilename)) : null;
                }

                if (package == null)
                {
                    continue;
                }

                if ((entry = package.GetEntry(fileName.Substring(packageDirectory.Length + 1))) != null)
                {
                    stream          = entry.Open();
                    contentImporter = binaryLoader;
                    return(true);
                }
            }
            stream          = null;
            contentImporter = null;
            return(false);
        }
예제 #16
0
        public bool TryResolveContent(string fileName, IServiceProvider serviceProvider, out Stream stream, out IContentImporter contentImporter)
        {
            stream          = null;
            contentImporter = null;

            if (!File.Exists(fileName))
            {
                return(false);
            }

            stream = File.OpenRead(fileName);

            var importerFile = fileName + ".importer";

            if (File.Exists(importerFile))
            {
                contentImporter = xaml.Load <IContentImporter>(importerFile, serviceProvider);
            }
            else if (!importers.TryGetValue(Path.GetExtension(fileName), out contentImporter))
            {
                throw new InvalidOperationException("Cannot find importer for file: " + fileName);
            }

            return(true);
        }
예제 #17
0
 public static T Load <T>(this IContentImporter loader, Stream stream, IServiceProvider serviceProvider) where T : class
 {
     return(loader.Import(stream, serviceProvider) as T);
 }
예제 #18
0
 public ImporterInstance(ImporterType type)
 {
     Type     = type;
     Instance = type.CreateInstance();
 }