/// <summary> /// Initializes a new <see cref="LightClawModelPart"/>. /// </summary> /// <param name="effect">The <see cref="Effect"/>.</param> /// <param name="vao">The <see cref="VertexArrayObject"/>.</param> /// <param name="diffuse">The diffuse texture.</param> /// <param name="ownsEffect">Indicates whether the <paramref cref="effect"/> will be taken ownage of.</param> /// <param name="ownsVao">Indicates whether the <paramref cref="vao"/> will be taken ownage of.</param> /// <param name="ownsTexture">Indicates whether the <paramref cref="diffuse"/> texture will be taken ownage of.</param> public LightClawModelPart(Effect effect, VertexArrayObject vao, Texture2D diffuse, bool ownsEffect, bool ownsVao, bool ownsTexture) : base(effect, vao, ownsEffect, ownsVao) { Contract.Requires<ArgumentNullException>(effect != null); Contract.Requires<ArgumentNullException>(vao != null); this.Diffuse = diffuse; this.OwnsDiffuse = ownsTexture; }
/// <summary> /// Initializes a new <see cref="ModelPart"/> and sets <see cref="P:Material"/> and <see cref="P:Vao"/>. /// </summary> /// <param name="effect">The <see cref="Effect"/> used to shade the <see cref="ModelPart"/>.</param> /// <param name="vao">The <see cref="VertexArrayObject"/> storing the geometry data.</param> /// <param name="ownsEffect">Indicates whether the <paramref cref="effect"/> will be taken ownage of.</param> /// <param name="ownsEffect">Indicates whether the <paramref cref="vao"/> will be taken ownage of.</param> protected ModelPart(Effect effect, VertexArrayObject vao, bool ownsEffect, bool ownsVao) { Contract.Requires<ArgumentNullException>(effect != null); Contract.Requires<ArgumentNullException>(vao != null); this.Effect = effect; this.OwnsEffect = ownsEffect; this.OwnsVao = ownsVao; this.Vao = vao; }
/// <summary> /// Initializes a new <see cref="LightClawModelPart"/>. /// </summary> /// <param name="effect">The <see cref="Effect"/>.</param> /// <param name="vao">The <see cref="VertexArrayObject"/>.</param> public LightClawModelPart(Effect effect, VertexArrayObject vao, Texture2D diffuse) : this(effect, vao, diffuse, false, true, false) { Contract.Requires<ArgumentNullException>(effect != null); Contract.Requires<ArgumentNullException>(vao != null); }
public async Task<object> ReadAsync(ContentReadParameters parameters) { Func<AssimpScene> f = () => { parameters.CancellationToken.ThrowIfCancellationRequested(); return this.context.ImportFileFromStream( parameters.AssetStream, postProcessingSteps, Path.GetExtension(parameters.ResourceString) ); }; Task<Effect> shaderLoadTask = parameters.ContentManager.LoadAsync<Effect>("Shaders/Basic.fx", parameters.CancellationToken); AssimpScene s = this.Dispatcher.IsOnThread ? await Task.Run(f).ConfigureAwait(false) : f(); // Make sure we don't pollute the main thread with IO ConcurrentDictionary<AssimpMesh, MeshInfo> meshData = new ConcurrentDictionary<AssimpMesh, MeshInfo>(); // Two separate tasks since one of them can be loaded asynchronously, and the other one // must be loaded on the main thread. Task textureLoadTask = Task.WhenAll(s.Meshes.Select(async mesh => { Material mat = s.Materials[mesh.MaterialIndex]; Texture2D tex2D = await parameters.ContentManager.LoadAsync<Texture2D>( mat.HasTextureDiffuse ? Path.Combine(Path.GetDirectoryName(parameters.ResourceString), mat.TextureDiffuse.FilePath) : "Internals/Default.png", parameters.CancellationToken ).ConfigureAwait(false); meshData.AddOrUpdate(mesh, new MeshInfo() { Texture = tex2D }, (m, mi) => { mi.Texture = tex2D; return mi; }); })); Task vaoCreateTask = this.Dispatcher.ImmediateOr(() => { foreach (AssimpMesh mesh in s.Meshes) { if (!mesh.HasVertices) { this.Log.Warn(() => string.Format("Mesh {0} does not have vertex data! It will not be loaded.", mesh.Name)); continue; } VertexArrayObject vao = new VertexArrayObject( BufferObject.Create(mesh.GetIndicesUInt16(), BufferTarget.ElementArrayBuffer), new BufferDescription( BufferObject.Create(mesh.Normals.ToArray(), BufferTarget.ArrayBuffer), new VertexAttributePointer(VertexAttributeLocation.Normals, 3, VertexAttribPointerType.Float, false, 0, 0) ), new BufferDescription( mesh.HasTextureCoords(0) ? BufferObject.Create(mesh.TextureCoordinateChannels[0].Select(v => new Vector2(v.X, v.Y)).ToArray(), BufferTarget.ArrayBuffer) : null, new VertexAttributePointer(VertexAttributeLocation.TexCoords, 2, VertexAttribPointerType.Float, false, 0, 0) ), new BufferDescription( BufferObject.Create(mesh.Vertices.ToArray(), BufferTarget.ArrayBuffer), new VertexAttributePointer(VertexAttributeLocation.Position, 3, VertexAttribPointerType.Float, false, 0, 0) ) ); meshData.AddOrUpdate(mesh, new MeshInfo() { Vao = vao }, (m, mi) => { mi.Vao = vao; return mi; }); } }, DispatcherPriority.Normal); // Calculate vertex data size, and if it surpasses 85kb, turn on LoH compaction if (s.Meshes.Any(mesh => (mesh.VertexCount * 3 * 4) >= 85000)) { GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; } await Task.WhenAll(shaderLoadTask, textureLoadTask, vaoCreateTask).ConfigureAwait(false); IEnumerable<ModelPart> modelParts = meshData.Values.Select(mi => new LightClawModelPart(shaderLoadTask.Result, mi.Vao, mi.Texture, false, true, false)); return new Model(s.HasMeshes ? s.Meshes[0].Name : null, modelParts, true); }
/// <summary> /// Initializes a new <see cref="ModelPart"/> and sets <see cref="P:Material"/> and <see cref="P:Vao"/>. /// </summary> /// <param name="effect">The <see cref="Effect"/> used to shade the <see cref="ModelPart"/>.</param> /// <param name="vao">The <see cref="VertexArrayObject"/> storing the geometry data. Will be taken ownage of.</param> protected ModelPart(Effect effect, VertexArrayObject vao) : this(effect, vao, false, true) { Contract.Requires<ArgumentNullException>(effect != null); Contract.Requires<ArgumentNullException>(vao != null); }