Exemplo n.º 1
0
        /// <summary>
        /// Load an asset to the preview.
        /// </summary>
        /// <typeparam name="TAssetType">The type of the asset to load</typeparam>
        /// <param name="url">The path to the asset to load</param>
        /// <param name="settings">The settings. If null, fallback to <see cref="ContentManagerLoaderSettings.Default" />.</param>
        /// <returns>The loaded asset</returns>
        public TAssetType LoadAsset <TAssetType>(string url, ContentManagerLoaderSettings settings = null) where TAssetType : class
        {
            TAssetType result = null;

            try
            {
                // This method can be invoked both from a script and from a regular task. In the second case, it will use the out-of-microthread database which need to be locked.
                // TODO: Ensure this method is always called from the preview game (it is not at least when a property is modified, currently), so we don't need to lock. Note: should be the case now, assume it is after GDC!
                if (Scheduler.CurrentMicroThread == null)
                {
                    Monitor.Enter(AssetBuilderService.OutOfMicrothreadDatabaseLock);
                }

                MicrothreadLocalDatabases.MountDatabase(OutputObjects.Yield());

                try
                {
                    result = Game.Content.Load <TAssetType>(url, settings);
                }
                finally
                {
                    if (Scheduler.CurrentMicroThread == null)
                    {
                        MicrothreadLocalDatabases.UnmountDatabase();
                    }
                }
            }
            catch (Exception e)
            {
                Builder.Logger.Error($"An exception was triggered when trying to load the entity [{url}] for the preview of asset item [{AssetItem.Location}].", e);
            }
            finally
            {
                if (Scheduler.CurrentMicroThread == null)
                {
                    Monitor.Exit(AssetBuilderService.OutOfMicrothreadDatabaseLock);
                }
            }
            return(result);
        }
Exemplo n.º 2
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 ContentManagerLoaderSettings
                {
                    ContentFilter = ContentManagerLoaderSettings.NewContentFilterByType(typeof(Mesh), typeof(Material))
                };

                IList <Entity> allEntities = new List <Entity>();

                if (Parameters.Prefab != null)
                {
                    var prefab = Package.Session.FindAssetFromProxyObject(Parameters.Prefab)?.Asset as PrefabAsset;
                    if (prefab != null)
                    {
                        allEntities = prefab.Hierarchy.Parts.Values.Select(x => x.Entity).ToList();
                    }
                }

                var prefabModel = new 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 loadedModel = new List <Model>();

                foreach (var subEntity in allEntities)
                {
                    var modelComponent = subEntity.Get <ModelComponent>();

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

                    var modelAsset = Package.Session.FindAssetFromProxyObject(modelComponent.Model);
                    if (modelAsset == null)
                    {
                        continue;
                    }

                    var model = contentManager.Load <Model>(modelAsset.Location, loadSettings);
                    loadedModel.Add(model);

                    if (model == null ||
                        model.Meshes.Any(x => x.Draw.PrimitiveType != PrimitiveType.TriangleList || x.Draw.VertexBuffers == null || x.Draw.VertexBuffers.Length != 1) ||
                        model.Materials.Any(x => x.Material != null && x.Material.Passes.Any(pass => pass.HasTransparency)) ||
                        modelComponent.Materials.Values.Any(x => x.Passes.Any(pass => pass.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;
                    }

                    for (var index = 0; index < model.Materials.Count; index++)
                    {
                        var material = model.Materials[index];
                        var mat      = ExtractMaterialInstance(material, index, modelComponent, fallbackMaterial);

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

                        if (materials.TryGetValue(mat, out var 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);

                foreach (var model in loadedModel.NotNull())
                {
                    contentManager.Unload(model);
                }
                device.Dispose();

                return(Task.FromResult(ResultStatus.Successful));
            }
Exemplo n.º 3
0
            protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                var assetManager = new ContentManager();

                // Cloned list of collider shapes
                var descriptions = Parameters.ColliderShapes.ToList();

                Parameters.ColliderShapes = Parameters.ColliderShapes.Where(x => x != null &&
                                                                            (x.GetType() != typeof(ConvexHullColliderShapeDesc) || ((ConvexHullColliderShapeDesc)x).Model != null)).ToList();

                //pre process special types
                foreach (var convexHullDesc in
                         (from shape in Parameters.ColliderShapes let type = shape.GetType() where type == typeof(ConvexHullColliderShapeDesc) select shape)
                         .Cast <ConvexHullColliderShapeDesc>())
                {
                    // Clone the convex hull shape description so the fields that should not be serialized can be cleared (Model in this case)
                    ConvexHullColliderShapeDesc convexHullDescClone = new ConvexHullColliderShapeDesc
                    {
                        Scaling       = convexHullDesc.Scaling,
                        LocalOffset   = convexHullDesc.LocalOffset,
                        LocalRotation = convexHullDesc.LocalRotation,
                        Depth         = convexHullDesc.Depth,
                        PosSampling   = convexHullDesc.PosSampling,
                        AngleSampling = convexHullDesc.AngleSampling,
                        PosRefine     = convexHullDesc.PosRefine,
                        AngleRefine   = convexHullDesc.AngleRefine,
                        Alpha         = convexHullDesc.Alpha,
                        Threshold     = convexHullDesc.Threshold,
                    };

                    // Replace shape in final result with cloned description
                    int replaceIndex = descriptions.IndexOf(convexHullDesc);
                    descriptions[replaceIndex] = convexHullDescClone;

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

                    var modelAsset = assetManager.Load <Model>(AttachedReferenceManager.GetUrl(convexHullDesc.Model), loadSettings);
                    if (modelAsset == null)
                    {
                        continue;
                    }

                    convexHullDescClone.ConvexHulls        = new List <List <List <Vector3> > >();
                    convexHullDescClone.ConvexHullsIndices = new List <List <List <uint> > >();

                    commandContext.Logger.Info("Processing convex hull generation, this might take a while!");

                    var nodeTransforms = new List <Matrix>();

                    //pre-compute all node transforms, assuming nodes are ordered... see ModelViewHierarchyUpdater

                    if (modelAsset.Skeleton == null)
                    {
                        Matrix baseMatrix;
                        Matrix.Transformation(ref convexHullDescClone.Scaling, ref convexHullDescClone.LocalRotation, ref convexHullDescClone.LocalOffset, out baseMatrix);
                        nodeTransforms.Add(baseMatrix);
                    }
                    else
                    {
                        var nodesLength = modelAsset.Skeleton.Nodes.Length;
                        for (var i = 0; i < nodesLength; i++)
                        {
                            Matrix localMatrix;
                            Matrix.Transformation(
                                ref modelAsset.Skeleton.Nodes[i].Transform.Scale,
                                ref modelAsset.Skeleton.Nodes[i].Transform.Rotation,
                                ref modelAsset.Skeleton.Nodes[i].Transform.Position, out localMatrix);

                            Matrix worldMatrix;
                            if (modelAsset.Skeleton.Nodes[i].ParentIndex != -1)
                            {
                                var nodeTransform = nodeTransforms[modelAsset.Skeleton.Nodes[i].ParentIndex];
                                Matrix.Multiply(ref localMatrix, ref nodeTransform, out worldMatrix);
                            }
                            else
                            {
                                worldMatrix = localMatrix;
                            }

                            if (i == 0)
                            {
                                Matrix baseMatrix;
                                Matrix.Transformation(ref convexHullDescClone.Scaling, ref convexHullDescClone.LocalRotation, ref convexHullDescClone.LocalOffset, out baseMatrix);
                                nodeTransforms.Add(baseMatrix * worldMatrix);
                            }
                            else
                            {
                                nodeTransforms.Add(worldMatrix);
                            }
                        }
                    }

                    for (var i = 0; i < nodeTransforms.Count; i++)
                    {
                        var i1 = i;
                        if (modelAsset.Meshes.All(x => x.NodeIndex != i1))
                        {
                            continue;                                                // no geometry in the node
                        }
                        var combinedVerts   = new List <float>();
                        var combinedIndices = new List <uint>();

                        var hullsList = new List <List <Vector3> >();
                        convexHullDescClone.ConvexHulls.Add(hullsList);

                        var indicesList = new List <List <uint> >();
                        convexHullDescClone.ConvexHullsIndices.Add(indicesList);

                        foreach (var meshData in modelAsset.Meshes.Where(x => x.NodeIndex == i1))
                        {
                            var indexOffset = (uint)combinedVerts.Count / 3;

                            var stride = meshData.Draw.VertexBuffers[0].Declaration.VertexStride;

                            var    vertexBufferRef = AttachedReferenceManager.GetAttachedReference(meshData.Draw.VertexBuffers[0].Buffer);
                            byte[] vertexData;
                            if (vertexBufferRef.Data != null)
                            {
                                vertexData = ((BufferData)vertexBufferRef.Data).Content;
                            }
                            else if (!vertexBufferRef.Url.IsNullOrEmpty())
                            {
                                var dataAsset = assetManager.Load <Buffer>(vertexBufferRef.Url);
                                vertexData = dataAsset.GetSerializationData().Content;
                            }
                            else
                            {
                                continue;
                            }

                            var vertexIndex = meshData.Draw.VertexBuffers[0].Offset;
                            for (var v = 0; v < meshData.Draw.VertexBuffers[0].Count; v++)
                            {
                                var posMatrix = Matrix.Translation(new Vector3(BitConverter.ToSingle(vertexData, vertexIndex + 0), BitConverter.ToSingle(vertexData, vertexIndex + 4), BitConverter.ToSingle(vertexData, vertexIndex + 8)));

                                Matrix rotatedMatrix;
                                var    nodeTransform = nodeTransforms[i];
                                Matrix.Multiply(ref posMatrix, ref nodeTransform, out rotatedMatrix);

                                combinedVerts.Add(rotatedMatrix.TranslationVector.X);
                                combinedVerts.Add(rotatedMatrix.TranslationVector.Y);
                                combinedVerts.Add(rotatedMatrix.TranslationVector.Z);

                                vertexIndex += stride;
                            }

                            var    indexBufferRef = AttachedReferenceManager.GetAttachedReference(meshData.Draw.IndexBuffer.Buffer);
                            byte[] indexData;
                            if (indexBufferRef.Data != null)
                            {
                                indexData = ((BufferData)indexBufferRef.Data).Content;
                            }
                            else if (!indexBufferRef.Url.IsNullOrEmpty())
                            {
                                var dataAsset = assetManager.Load <Buffer>(indexBufferRef.Url);
                                indexData = dataAsset.GetSerializationData().Content;
                            }
                            else
                            {
                                throw new Exception("Failed to find index buffer while building a convex hull.");
                            }

                            var indexIndex = meshData.Draw.IndexBuffer.Offset;
                            for (var v = 0; v < meshData.Draw.IndexBuffer.Count; v++)
                            {
                                if (meshData.Draw.IndexBuffer.Is32Bit)
                                {
                                    combinedIndices.Add(BitConverter.ToUInt32(indexData, indexIndex) + indexOffset);
                                    indexIndex += 4;
                                }
                                else
                                {
                                    combinedIndices.Add(BitConverter.ToUInt16(indexData, indexIndex) + indexOffset);
                                    indexIndex += 2;
                                }
                            }
                        }

                        var decompositionDesc = new ConvexHullMesh.DecompositionDesc
                        {
                            VertexCount   = (uint)combinedVerts.Count / 3,
                            IndicesCount  = (uint)combinedIndices.Count,
                            Vertexes      = combinedVerts.ToArray(),
                            Indices       = combinedIndices.ToArray(),
                            Depth         = convexHullDesc.Depth,
                            PosSampling   = convexHullDesc.PosSampling,
                            PosRefine     = convexHullDesc.PosRefine,
                            AngleSampling = convexHullDesc.AngleSampling,
                            AngleRefine   = convexHullDesc.AngleRefine,
                            Alpha         = convexHullDesc.Alpha,
                            Threshold     = convexHullDesc.Threshold,
                            SimpleHull    = convexHullDesc.SimpleWrap
                        };

                        var convexHullMesh = new ConvexHullMesh();

                        convexHullMesh.Generate(decompositionDesc);

                        var count = convexHullMesh.Count;

                        commandContext.Logger.Info("Node generated " + count + " convex hulls");

                        var vertexCountHull = 0;

                        for (uint h = 0; h < count; h++)
                        {
                            float[] points;
                            convexHullMesh.CopyPoints(h, out points);

                            var pointList = new List <Vector3>();

                            for (var v = 0; v < points.Length; v += 3)
                            {
                                var vert = new Vector3(points[v + 0], points[v + 1], points[v + 2]);
                                pointList.Add(vert);

                                vertexCountHull++;
                            }

                            hullsList.Add(pointList);

                            uint[] indices;
                            convexHullMesh.CopyIndices(h, out indices);

                            for (var t = 0; t < indices.Length; t += 3)
                            {
                                Utilities.Swap(ref indices[t], ref indices[t + 2]);
                            }

                            var indexList = new List <uint>(indices);

                            indicesList.Add(indexList);
                        }

                        convexHullMesh.Dispose();

                        commandContext.Logger.Info("For a total of " + vertexCountHull + " vertexes");
                    }
                }

                var runtimeShape = new PhysicsColliderShape {
                    Descriptions = descriptions
                };

                assetManager.Save(Url, runtimeShape);

                return(Task.FromResult(ResultStatus.Successful));
            }
Exemplo n.º 4
0
        /// <summary>
        /// Loads content from the specified URL asynchronously.
        /// </summary>
        /// <typeparam name="T">The content type.</typeparam>
        /// <param name="content">The <see cref="IContentManager"/>.</param>
        /// <param name="urlReference">The URL to load from.</param>
        /// <param name="settings">The settings. If null, fallback to <see cref="ContentManagerLoaderSettings.Default"/>.</param>
        /// <returns>The loaded content.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="urlReference"/> is <c>null</c> or <c>empty</c>. Or <paramref name="content"/> is <c>null</c>.</exception>
        public static Task <T> LoadAsync <T>(this IContentManager content, UrlReference <T> urlReference, ContentManagerLoaderSettings settings = null)
            where T : class
        {
            CheckArguments(content, urlReference);

            return(content.LoadAsync <T>(urlReference.Url, settings));
        }
Exemplo n.º 5
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 ContentManagerLoaderSettings
                {
                    ContentFilter = ContentManagerLoaderSettings.NewContentFilterByType(typeof(Mesh), typeof(Skeleton), typeof(Material), typeof(Prefab))
                };

                Prefab prefab;

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

                var prefabModel = new 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?.Model == null || (modelComponent.Skeleton != null && modelComponent.Skeleton.Nodes.Length != 1))
                        {
                            continue;
                        }

                        var modelAsset = contentManager.Load <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.Values.Any(x => 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 <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));
            }
Exemplo n.º 6
0
        public async Task Run()
        {
            Services = new ServiceRegistry();

            // Database file provider
            Services.AddService <IDatabaseFileProviderService>(new DatabaseFileProviderService(new DatabaseFileProvider(ObjectDatabase.CreateDefaultDatabase())));

            // Content manager
            Content = new ContentManager(Services);
            Services.AddService <IContentManager>(Content);
            Services.AddService(Content);

            //Services.AddService<IGraphicsDeviceService>(new GraphicsDeviceServiceLocal(null));

            // Game systems
            var gameSystems = new GameSystemCollection(Services);

            Services.AddService <IGameSystemCollection>(gameSystems);
            gameSystems.Initialize();

            // Load scene (physics only)
            var loadSettings = new ContentManagerLoaderSettings
            {
                // Ignore all references (Model, etc...)
                ContentFilter = ContentManagerLoaderSettings.NewContentFilterByType()
            };
            var scene = await Content.LoadAsync <Scene>("MainScene", loadSettings);

            var sceneInstance = new SceneInstance(Services, scene, ExecutionMode.None);
            var sceneSystem   = new SceneSystem(Services)
            {
                SceneInstance = sceneInstance,
            };

            Services.AddService(sceneSystem);

            var physics = new PhysicsProcessor();

            sceneInstance.Processors.Add(physics);

            var socket = new SimpleSocket();

            socket.Connected += clientSocket =>
            {
                Console.WriteLine("Client connected");

                var reader = new BinarySerializationReader(clientSocket.ReadStream);
                while (true)
                {
                    // Receive ray start/end
                    var start = reader.Read <Vector3>();
                    var end   = reader.Read <Vector3>();
                    // Raycast
                    var result = physics.Simulation.Raycast(start, end);
                    Console.WriteLine($"Performing raycast: {(result.Succeeded ? "hit" : "miss")}");
                    // Send result
                    clientSocket.WriteStream.WriteByte((byte)(result.Succeeded ? 1 : 0));
                    clientSocket.WriteStream.Flush();
                }
            };
            await socket.StartServer(2655, false);

            Console.WriteLine("Server listening, press a key to exit");
            Console.ReadKey();
        }