示例#1
0
        public override void Init(ResourceManager resourceManager)
        {
            Material pbrMat = new Rendering.Material(resourceManager.Shaders.GetFromAlias("PBR").Shader);
            Material uiMat  = new Rendering.Material(resourceManager.Shaders.GetFromAlias("UI").Shader);

            pbrMat.AddTexture((int)Rendering.TextureMap.Albedo, resourceManager.Textures.GetFromAlias("Diffuse").Texture);
            pbrMat.AddTexture((int)Rendering.TextureMap.Normal, resourceManager.Textures.GetFromAlias("Normal").Texture);
            pbrMat.AddTexture((int)Rendering.TextureMap.Roughness, resourceManager.Textures.GetFromAlias("Roughness").Texture);
            pbrMat.AddTexture((int)Rendering.TextureMap.Metallic, resourceManager.Textures.GetFromAlias("Metallic").Texture);

            uiMat.AddTexture((int)Rendering.TextureMap.Normal, resourceManager.Textures.GetFromAlias("Normal").Texture);
            uiMat.AddTexture((int)Rendering.TextureMap.Albedo, resourceManager.Textures.GetFromAlias("Diffuse").Texture);
            uiMat.AddTexture((int)Rendering.TextureMap.Roughness, resourceManager.Textures.GetFromAlias("Roughness").Texture);
            uiMat.AddTexture((int)Rendering.TextureMap.Metallic, resourceManager.Textures.GetFromAlias("Metallic").Texture);


            Rendering.Model monkeyModel = new Rendering.Model(resourceManager.Meshes.GetFromAlias("Barrel").Mesh, pbrMat);
            Rendering.Model sphereModel = new Rendering.Model(resourceManager.Meshes.GetFromAlias("Sphere").Mesh, pbrMat);
            Rendering.Model planeModel  = new Rendering.Model(resourceManager.Meshes.GetFromAlias("Plane").Mesh, pbrMat);


            sphere.Components.Create <ComponentSystem._ModelComponent>();
            sphere.Components.Get <ComponentSystem._ModelComponent>().Model = sphereModel;

            testObject.Components.Create <ComponentSystem._ModelComponent>();
            testObject.Components.Get <ComponentSystem._ModelComponent>().Model = monkeyModel;

            testUI.Components.Create <ComponentSystem._ModelComponent>();
            testUI.Components.Get <ComponentSystem._ModelComponent>().Model = new Rendering.UI.UIRect(new RectangleF(3, 0, 256, 256), uiMat);

            groundPlane.Components.Create <ComponentSystem._ModelComponent>();
            groundPlane.Components.Get <ComponentSystem._ModelComponent>().Model = planeModel;
        }
示例#2
0
        /// <summary>
        /// Refine the mesh groups based on the result of the delegate test method.
        /// </summary>
        /// <param name="meshList">The list of mesh groups.</param>
        /// <param name="sameGroupDelegate">The test delegate.</param>
        /// <returns>The new list of mesh groups.</returns>
        private List <GroupList <int, Mesh> > RefineGroups(Rendering.Model model, List <GroupList <int, Mesh> > meshList, SameGroup sameGroupDelegate)
        {
            var finalGroups = new List <GroupList <int, Mesh> >();

            foreach (var meshGroup in meshList)
            {
                var updatedGroups = new List <GroupList <int, Mesh> >();
                foreach (var mesh in meshGroup)
                {
                    var createNewGroup = true;
                    foreach (var sameParamsMeshes in updatedGroups)
                    {
                        if (sameGroupDelegate(model, sameParamsMeshes[0], mesh))
                        {
                            sameParamsMeshes.Add(mesh);
                            createNewGroup = false;
                            break;
                        }
                    }

                    if (createNewGroup)
                    {
                        var newGroup = new GroupList <int, Mesh> {
                            Key = meshGroup.Key
                        };
                        newGroup.Add(mesh);
                        updatedGroups.Add(newGroup);
                    }
                }
                finalGroups.AddRange(updatedGroups);
            }
            return(finalGroups);
        }
示例#3
0
        /// <summary>
        /// Compares the shadow options between the two meshes.
        /// </summary>
        /// <param name="baseMesh">The base mesh.</param>
        /// <param name="newMesh">The mesh to compare.</param>
        /// <param name="extra">Unused parameter.</param>
        /// <returns>True if the options are the same, false otherwise.</returns>
        private static bool CompareShadowOptions(Rendering.Model model, Mesh baseMesh, Mesh newMesh)
        {
            // TODO: Check is Model the same for the two mesh?
            var material1 = model.Materials.GetItemOrNull(baseMesh.MaterialIndex);
            var material2 = model.Materials.GetItemOrNull(newMesh.MaterialIndex);

            return(material1 == material2 || (material1 != null && material2 != null && material1.IsShadowCaster == material2.IsShadowCaster &&
                                              material1.IsShadowReceiver == material2.IsShadowReceiver));
        }
示例#4
0
        /// <summary>
        /// Compares the parameters of the two meshes.
        /// </summary>
        /// <param name="baseMesh">The base mesh.</param>
        /// <param name="newMesh">The mesh to compare.</param>
        /// <param name="extra">Unused parameter.</param>
        /// <returns>True if all the parameters are the same, false otherwise.</returns>
        private static bool CompareParameters(Rendering.Model model, Mesh baseMesh, Mesh newMesh)
        {
            var localParams = baseMesh.Parameters;

            if (localParams == null && newMesh.Parameters == null)
            {
                return(true);
            }
            if (localParams == null || newMesh.Parameters == null)
            {
                return(false);
            }
            return(IsSubsetOf(localParams, newMesh.Parameters) && IsSubsetOf(newMesh.Parameters, localParams));
        }
示例#5
0
        /// <summary>
        /// Compares the parameters of the two meshes.
        /// </summary>
        /// <param name="baseMesh">The base mesh.</param>
        /// <param name="newMesh">The mesh to compare.</param>
        /// <param name="extra">Unused parameter.</param>
        /// <returns>True if all the parameters are the same, false otherwise.</returns>
        private static bool CompareParameters(Rendering.Model model, Mesh baseMesh, Mesh newMesh)
        {
            var localParams = baseMesh.Parameters;

            if (localParams == null && newMesh.Parameters == null)
            {
                return(true);
            }
            if (localParams == null || newMesh.Parameters == null)
            {
                return(false);
            }
            return(AreCollectionsEqual(localParams, newMesh.Parameters));
        }
示例#6
0
        /// <summary>
        /// Create groups of mergeable meshes.
        /// </summary>
        /// <param name="model">The current model.</param>
        /// <param name="index">The index of the currently visited node.</param>
        /// <param name="nodeBlackList">List of the nodes that should be kept.</param>
        /// <param name="meshes">The meshes and their node index.</param>
        /// <param name="finalLists">List of mergeable meshes and their root node.</param>
        /// <returns>A list of mergeable meshes in progress.</returns>
        private Dictionary <int, List <Mesh> > GroupFromIndex(Rendering.Model model, int index, HashSet <int> nodeBlackList, List <Mesh> meshes, List <GroupList <int, Mesh> > finalLists)
        {
            var children = GetChildren(model.Hierarchy.Nodes, index);

            var materialGroups = new Dictionary <int, List <Mesh> >();

            // Get the group from each child
            foreach (var child in children)
            {
                var newMaterialGroups = GroupFromIndex(model, child, nodeBlackList, meshes, finalLists);

                foreach (var group in newMaterialGroups)
                {
                    if (!materialGroups.ContainsKey(group.Key))
                    {
                        materialGroups.Add(group.Key, new List <Mesh>());
                    }
                    materialGroups[group.Key].AddRange(group.Value);
                }
            }

            // Add the current node if it has a mesh
            foreach (var nodeMesh in meshes.Where(x => x.NodeIndex == index))
            {
                var matId = nodeMesh.MaterialIndex;
                if (!materialGroups.ContainsKey(matId))
                {
                    materialGroups.Add(matId, new List <Mesh>());
                }
                materialGroups[matId].Add(nodeMesh);
            }

            // Store the generated list as final if the node should be kept
            if (nodeBlackList.Contains(index) || index == 0)
            {
                foreach (var materialGroup in materialGroups)
                {
                    var groupList = new GroupList <int, Mesh>();
                    groupList.Key = index;
                    groupList.AddRange(materialGroup.Value);
                    finalLists.Add(groupList);
                }
                materialGroups.Clear();
            }

            return(materialGroups);
        }
示例#7
0
        public static void DrawModel(Rendering.Renderer rend)
        {
            Rendering.Model mtm = rend.model;

            Vector     euler = rend.matrix.eulerAngles;
            Quaternion q     = Quaternion.RotationYawPitchRoll(euler.y * Mathf.Deg2Rad, euler.x * Mathf.Deg2Rad, euler.z * Mathf.Deg2Rad);

            Matrix matrix = new Matrix();

            matrix.AffineTransformation(rend.matrix.scale.y, Vector.zero, q, rend.matrix.position);

            for (int i = 0; i < mtm.materials.Length; i++)
            {
                device.SetTransform(TransformType.World, matrix);
                device.Material = mtm.materials[i].material;
                device.SetTexture(0, mtm.materials[i].texture);
                mtm.mesh.DrawSubset(i);
            }
        }
示例#8
0
 internal void Load()
 {
     Rendering.Model model = new Rendering.Model("Baby", "Phong");
     objects.Add(model);
 }
示例#9
0
            private static void ProcessMaterial(ContentManager manager, ICollection <EntityChunk> chunks, MaterialInstance material, Rendering.Model prefabModel)
            {
                //we need to futher group by VertexDeclaration
                var meshes = new Dictionary <VertexDeclaration, MeshData>();

                //actually create the mesh
                foreach (var chunk in chunks)
                {
                    foreach (var modelMesh in chunk.Model.Meshes)
                    {
                        //process only right material
                        if (modelMesh.MaterialIndex == chunk.MaterialIndex)
                        {
                            MeshData mesh;
                            if (!meshes.TryGetValue(modelMesh.Draw.VertexBuffers[0].Declaration, out mesh))
                            {
                                mesh = new MeshData {
                                    VertexStride = modelMesh.Draw.VertexBuffers[0].Stride
                                };
                                meshes.Add(modelMesh.Draw.VertexBuffers[0].Declaration, mesh);
                            }

                            //vertexes
                            var    vertexBufferRef = AttachedReferenceManager.GetAttachedReference(modelMesh.Draw.VertexBuffers[0].Buffer);
                            byte[] vertexData;
                            if (vertexBufferRef.Data != null)
                            {
                                vertexData = ((BufferData)vertexBufferRef.Data).Content;
                            }
                            else if (!vertexBufferRef.Url.IsNullOrEmpty())
                            {
                                var dataAsset = manager.Load <Graphics.Buffer>(vertexBufferRef.Url);
                                vertexData = dataAsset.GetSerializationData().Content;
                            }
                            else
                            {
                                throw new Exception($"Failed to get Vertex BufferData for entity {chunk.Entity.Name}'s model.");
                            }

                            //transform the vertexes according to the entity
                            var vertexDataCopy = vertexData.ToArray();
                            chunk.Entity.Transform.UpdateWorldMatrix(); //make sure matrix is computed
                            modelMesh.Draw.VertexBuffers[0].TransformBuffer(vertexDataCopy, ref chunk.Entity.Transform.WorldMatrix);

                            //add to the big single array
                            var vertexes = vertexDataCopy
                                           .Skip(modelMesh.Draw.VertexBuffers[0].Offset)
                                           .Take(modelMesh.Draw.VertexBuffers[0].Count * modelMesh.Draw.VertexBuffers[0].Stride)
                                           .ToArray();

                            mesh.VertexData.AddRange(vertexes);

                            //indices
                            var    indexBufferRef = AttachedReferenceManager.GetAttachedReference(modelMesh.Draw.IndexBuffer.Buffer);
                            byte[] indexData;
                            if (indexBufferRef.Data != null)
                            {
                                indexData = ((BufferData)indexBufferRef.Data).Content;
                            }
                            else if (!indexBufferRef.Url.IsNullOrEmpty())
                            {
                                var dataAsset = manager.Load <Graphics.Buffer>(indexBufferRef.Url);
                                indexData = dataAsset.GetSerializationData().Content;
                            }
                            else
                            {
                                throw new Exception("Failed to get Indices BufferData for entity {chunk.Entity.Name}'s model.");
                            }

                            var indexSize = modelMesh.Draw.IndexBuffer.Is32Bit ? sizeof(uint) : sizeof(ushort);

                            var indices = indexData
                                          .Skip(modelMesh.Draw.IndexBuffer.Offset)
                                          .Take(modelMesh.Draw.IndexBuffer.Count * indexSize)
                                          .ToArray();

                            //todo this code is not optimal, use unsafe

                            //must convert to 32bits
                            if (indexSize == sizeof(ushort))
                            {
                                var uintIndex = new List <byte>();
                                for (var i = 0; i < indices.Length; i += sizeof(ushort))
                                {
                                    var index = BitConverter.ToUInt16(indices, i);
                                    var bi    = BitConverter.GetBytes((uint)index);
                                    uintIndex.Add(bi[0]);
                                    uintIndex.Add(bi[1]);
                                    uintIndex.Add(bi[2]);
                                    uintIndex.Add(bi[3]);
                                }
                                indices = uintIndex.ToArray();
                            }

                            //need to offset the indices
                            for (var i = 0; i < indices.Length; i += sizeof(uint))
                            {
                                var index = BitConverter.ToUInt32(indices, i) + mesh.IndexOffset;
                                var bi    = BitConverter.GetBytes(index);
                                indices[i + 0] = bi[0];
                                indices[i + 1] = bi[1];
                                indices[i + 2] = bi[2];
                                indices[i + 3] = bi[3];
                            }

                            mesh.IndexOffset += modelMesh.Draw.VertexBuffers[0].Count;

                            mesh.IndexData.AddRange(indices);
                        }
                    }
                }

                //Sort out material
                var matIndex = prefabModel.Materials.Count;

                prefabModel.Materials.Add(material);

                foreach (var meshData in meshes)
                {
                    //todo need to take care of short index
                    var vertexArray = meshData.Value.VertexData.ToArray();
                    var indexArray  = meshData.Value.IndexData.ToArray();

                    var vertexCount = vertexArray.Length / meshData.Value.VertexStride;
                    var indexCount  = indexArray.Length / 4;

                    var gpuMesh = new Mesh
                    {
                        Draw = new MeshDraw {
                            PrimitiveType = PrimitiveType.TriangleList, DrawCount = indexCount, StartLocation = 0
                        },
                        MaterialIndex = matIndex
                    };

                    var vertexBuffer = new BufferData(BufferFlags.VertexBuffer, new byte[vertexArray.Length]);
                    var indexBuffer  = new BufferData(BufferFlags.IndexBuffer, new byte[indexArray.Length]);

                    var vertexBufferSerializable = vertexBuffer.ToSerializableVersion();
                    var indexBufferSerializable  = indexBuffer.ToSerializableVersion();

                    Array.Copy(vertexArray, vertexBuffer.Content, vertexArray.Length);
                    Array.Copy(indexArray, indexBuffer.Content, indexArray.Length);

                    gpuMesh.Draw.VertexBuffers    = new VertexBufferBinding[1];
                    gpuMesh.Draw.VertexBuffers[0] = new VertexBufferBinding(vertexBufferSerializable, meshData.Key, vertexCount);
                    gpuMesh.Draw.IndexBuffer      = new IndexBufferBinding(indexBufferSerializable, true, indexCount);

                    prefabModel.Meshes.Add(gpuMesh);
                }
            }
示例#10
0
            protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                var contentManager = new ContentManager();

                var device = GraphicsDevice.New();

                var fallbackMaterial = Material.New(device, new MaterialDescriptor
                {
                    Attributes =
                    {
                        Diffuse      = new MaterialDiffuseMapFeature(new ComputeTextureColor()),
                        DiffuseModel = new MaterialDiffuseLambertModelFeature()
                    }
                });

                var loadSettings = new AssetManagerLoaderSettings
                {
                    ContentFilter = AssetManagerLoaderSettings.NewContentFilterByType(typeof(Mesh), typeof(Skeleton), typeof(Material), typeof(Prefab))
                };

                Prefab prefab;

                if (AssetParameters.Prefab == null)
                {
                    prefab = new Prefab();
                }
                else
                {
                    prefab = contentManager.Load <Prefab>(AssetParameters.Prefab.Location, loadSettings);
                    if (prefab == null)
                    {
                        throw new Exception("Failed to load prefab.");
                    }
                }

                var prefabModel = new Rendering.Model();

                //The objective is to create 1 mesh per material/shadow params
                //1. We group by materials
                //2. Create a mesh per material (might need still more meshes if 16bit indexes or more then 32bit)

                var materials = new Dictionary <MaterialInstance, List <EntityChunk> >();

                var validEntities = new List <Entity>();

                foreach (var rootEntity in prefab.Entities)
                {
                    //collect sub entities as well
                    var collected = IterateTree(rootEntity, subEntity => subEntity.GetChildren()).ToArray();

                    //first pass, check if compatible with prefabmodel
                    foreach (var subEntity in collected)
                    {
                        //todo for now we collect everything with a model component
                        var modelComponent = subEntity.Get <ModelComponent>();

                        if (modelComponent == null || modelComponent.Skeleton.Nodes.Length != 1)
                        {
                            continue;
                        }

                        var modelAsset = contentManager.Load <Rendering.Model>(AttachedReferenceManager.GetUrl(modelComponent.Model), loadSettings);
                        if (modelAsset == null ||
                            modelAsset.Meshes.Any(x => x.Draw.PrimitiveType != PrimitiveType.TriangleList || x.Draw.VertexBuffers == null || x.Draw.VertexBuffers.Length != 1) ||
                            modelAsset.Materials.Any(x => x.Material != null && x.Material.HasTransparency) ||
                            modelComponent.Materials.Any(x => x != null && x.HasTransparency)) //For now we limit only to TriangleList types and interleaved vertex buffers, also we skip transparent

                        {
                            commandContext.Logger.Info($"Skipped entity {subEntity.Name} since it's not compatible with PrefabModel.");
                            continue;
                        }

                        validEntities.Add(subEntity);
                    }
                }

                foreach (var subEntity in validEntities)
                {
                    var modelComponent = subEntity.Get <ModelComponent>();
                    var modelAsset     = contentManager.Load <Rendering.Model>(AttachedReferenceManager.GetUrl(modelComponent.Model), loadSettings);
                    for (var index = 0; index < modelAsset.Materials.Count; index++)
                    {
                        var material = modelAsset.Materials[index];
                        var mat      = ExtractMaterialInstance(material, index, modelComponent, fallbackMaterial);

                        var chunk = new EntityChunk {
                            Entity = subEntity, Model = modelAsset, MaterialIndex = index
                        };

                        List <EntityChunk> entities;
                        if (materials.TryGetValue(mat, out entities))
                        {
                            entities.Add(chunk);
                        }
                        else
                        {
                            materials.Add(mat, new List <EntityChunk> {
                                chunk
                            });
                        }
                    }
                }

                foreach (var material in materials)
                {
                    ProcessMaterial(contentManager, material.Value, material.Key, prefabModel);
                }

                // split the meshes if necessary
                prefabModel.Meshes = SplitExtensions.SplitMeshes(prefabModel.Meshes, renderingSettings.DefaultGraphicsProfile > GraphicsProfile.Level_9_3);

                //handle boundng box/sphere
                var modelBoundingBox    = prefabModel.BoundingBox;
                var modelBoundingSphere = prefabModel.BoundingSphere;

                foreach (var mesh in prefabModel.Meshes)
                {
                    var vertexBuffers = mesh.Draw.VertexBuffers;
                    if (vertexBuffers.Length > 0)
                    {
                        // Compute local mesh bounding box (no node transformation)
                        var matrix = Matrix.Identity;
                        mesh.BoundingBox = vertexBuffers[0].ComputeBounds(ref matrix, out mesh.BoundingSphere);

                        // Compute model bounding box (includes node transformation)
                        BoundingSphere meshBoundingSphere;
                        var            meshBoundingBox = vertexBuffers[0].ComputeBounds(ref matrix, out meshBoundingSphere);
                        BoundingBox.Merge(ref modelBoundingBox, ref meshBoundingBox, out modelBoundingBox);
                        BoundingSphere.Merge(ref modelBoundingSphere, ref meshBoundingSphere, out modelBoundingSphere);
                    }

                    mesh.Draw.CompactIndexBuffer();
                }
                prefabModel.BoundingBox    = modelBoundingBox;
                prefabModel.BoundingSphere = modelBoundingSphere;

                //save
                contentManager.Save(Url, prefabModel);

                device.Dispose();

                return(Task.FromResult(ResultStatus.Successful));
            }