internal override void InitFromAsset(Device device, CAsset asset) { CMeshAsset meshAsset = (CMeshAsset)asset; System.Diagnostics.Debug.Assert(meshAsset != null && meshAsset.IsLoaded); int sizePerVertex = Utilities.SizeOf <SVertexInfo>(); m_sizePerVertex = sizePerVertex; m_primitiveTopology = meshAsset.PrimitiveTopology; m_vertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, meshAsset.VertexData, sizePerVertex * meshAsset.VertexData.Length); m_vertexCount = meshAsset.VertexData.Length; m_primitiveCount = meshAsset.FaceCount; m_indexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, meshAsset.IndexData); m_indexCount = meshAsset.IndexData.Length; BoundingBox = new BoundingBox(meshAsset.AABBMin, meshAsset.AABBMax); BoundingSphere = SharpDX.BoundingSphere.FromBox(BoundingBox); if (meshAsset.MaterialAsset != null) { Material = CRenderer.Instance.ResourceManager.RequestResourceFromAsset <CMaterial>(meshAsset.MaterialAsset); } else { Material = CRenderer.Instance.ResourceManager.DefaultMaterial; } }
private void ProcessLoadRequest(SAssetLoadRequest loadRequest) { Scene scene = m_importer.ImportFile(loadRequest.filename, PostProcessPreset.TargetRealTimeMaximumQuality | PostProcessPreset.ConvertToLeftHanded); if (loadRequest.type == EAssetType.Mesh) { if (scene.HasMeshes) { CMeshAsset meshAsset = (CMeshAsset)loadRequest.targetAsset; CMeshLoadingJob loadingJob = new CMeshLoadingJob(scene, Path.GetDirectoryName(loadRequest.filename)); LoadMeshInternal(0, meshAsset, loadingJob, loadRequest.assetPath, Path.GetFileNameWithoutExtension(loadRequest.filename)); } } else if (loadRequest.type == EAssetType.Model) { if (scene.HasMeshes) { CModelAsset modelAsset = (CModelAsset)loadRequest.targetAsset; LoadModelInternal(loadRequest.filename, scene, modelAsset, loadRequest.assetPath); modelAsset.Name = Path.GetFileNameWithoutExtension(loadRequest.filename); if (CAssetRegistry.Instance.RequestRegisterAsset(modelAsset, loadRequest.assetPath + "Models/", out CModelAsset existingAsset)) { existingAsset.WaitUntilLoaded(); modelAsset.CopyFrom(existingAsset); } } } AssetLoadedCallback(loadRequest); }
private void AddMeshes(Node node, CModelAsset asset, string assetPath, CMeshLoadingJob loadingJob, ref Matrix transform) { Matrix previousTransform = transform; transform = Matrix.Multiply(previousTransform, FromAssimpMatrix(node.Transform)); if (node.HasMeshes) { foreach (int meshIndex in node.MeshIndices) { CMeshAsset meshAsset = new CMeshAsset(); // We always import all meshes in a file so we use always import here LoadMeshInternal(meshIndex, meshAsset, loadingJob, assetPath, null, true); meshAsset.LoadFinished(); SMeshChild modelChild = new SMeshChild() { meshAsset = meshAsset, relativeTransform = transform }; asset.MeshChildren.Add(modelChild); } } for (int i = 0; i < node.ChildCount; i++) { AddMeshes(node.Children[i], asset, assetPath, loadingJob, ref transform); } transform = previousTransform; }
public CMeshAsset LoadMeshAsset(string filename, bool bAlwaysImport = false) { // Block new loads and wait for our current load to finish m_bIsLoading = true; m_currentLoadTask?.Wait(); // Load the asset synchronous CMeshAsset outAsset = new CMeshAsset(); if (!bAlwaysImport && TryGetExistingAsset(filename, "Assets/", outAsset, out CMeshAsset existingAsset)) { m_bIsLoading = false; return(existingAsset); } Scene scene = m_importer.ImportFile(filename, PostProcessPreset.TargetRealTimeMaximumQuality | PostProcessPreset.ConvertToLeftHanded); if (scene.HasMeshes) { string basePath = Path.GetDirectoryName(filename); CMeshLoadingJob loadingJob = new CMeshLoadingJob(scene, basePath); LoadMeshInternal(0, outAsset, loadingJob, "Assets/", Path.GetFileNameWithoutExtension(filename), bAlwaysImport); } outAsset.LoadFinished(); // Unblock loader m_bIsLoading = false; // Continue loading request StartNextLoadRequest(); return(outAsset); }
private void OnSpawnCubeEntity(object arg) { CEngine.Instance.Dispatch(EEngineUpdatePriority.BeginFrame, () => { CMeshAsset cubeAsset = CImportManager.Instance.MeshImporter.LoadMeshAsync("TestResources/Cube.fbx"); CEntity cubeEntity = CEngine.Instance.CurrentWorld.SpawnEntity <CEntity>(); cubeEntity.AddComponent <CSceneComponent>(true, true); CMeshComponent meshComponent = cubeEntity.AddComponent <CMeshComponent>(true, true); meshComponent.LocalPosition = new Vector3(0, 0, 0.5f); meshComponent.Mesh = cubeAsset; SEntityId id = new SEntityId(cubeEntity.Id); Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => { Instance.SetSelectedObject(new CEditableObject(id)); })); UndoRedoUtility.Purge(null); }); }
public void EngineThread_SetPreviewMesh(CMeshAsset meshAsset, bool bKeepMaterial, bool bZoomToFit) { m_currentMeshAsset = meshAsset; CMaterial nodeMaterial = m_previewMesh?.GetOverrideMaterial(); if (m_previewMesh != null) { m_renderScene?.UnregisterRenderNode(m_previewMesh); } m_previewMesh = new CMeshRenderNode(null, meshAsset, null, m_previewMeshTransform); if (bKeepMaterial) { m_previewMesh.SetMaterialOverride(nodeMaterial); } m_renderScene?.RegisterRenderNode(m_previewMesh); if (bZoomToFit) { EngineThread_ZoomCameraToFitAsset(); } }
public CMeshAsset LoadMeshAsync(string filename, bool bAlwaysImport = false) { CMeshAsset outAsset = new CMeshAsset(); if (!bAlwaysImport && TryGetExistingAsset(filename, "Assets/", outAsset, out CMeshAsset existingAsset)) { return(existingAsset); } SAssetLoadRequest loadRequest = new SAssetLoadRequest() { filename = filename, targetAsset = outAsset, assetPath = "Assets/", type = EAssetType.Mesh }; m_loadRequests.Enqueue(loadRequest); StartNextLoadRequest(); return(outAsset); }
public bool Import(string filename, string importPath, bool bAlwaysImport = false) { // Block new loads and wait for our current load to finish m_bIsLoading = true; m_currentLoadTask?.Wait(); // Load the asset synchronous Scene scene = m_importer.ImportFile(filename, PostProcessPreset.TargetRealTimeMaximumQuality | PostProcessPreset.ConvertToLeftHanded); if (scene.HasMeshes) { if (scene.MeshCount > 1) { CModelAsset outModel = new CModelAsset(); LoadModelInternal(filename, scene, outModel, importPath); outModel.LoadFinished(); outModel.Name = Path.GetFileNameWithoutExtension(filename); if (CAssetRegistry.Instance.RequestRegisterAsset(outModel, importPath + "Models/", out CModelAsset existingModel, bAlwaysImport)) { existingModel.WaitUntilLoaded(); } } else { string basePath = Path.GetDirectoryName(filename); CMeshLoadingJob loadingJob = new CMeshLoadingJob(scene, basePath); CMeshAsset outMesh = new CMeshAsset(); LoadMeshInternal(0, outMesh, loadingJob, importPath, Path.GetFileNameWithoutExtension(filename), bAlwaysImport); outMesh.LoadFinished(); } } // Unblock loader m_bIsLoading = false; // Continue loading request StartNextLoadRequest(); return(true); }
public void Init(CInitializer initializer) { UpdateScheduler = new CUpdateScheduler(); CreateLevel(); GameConsole.Init(); PhysicsWorld.Init(this); #region Sponza CModelAsset sponzaAsset = CImportManager.Instance.MeshImporter.LoadModelAsync("TestResources/SponzaAtrium/sponza.obj"); m_sponzaEntity = SpawnEntity <CEntity>(); CModelComponent modelComponent = m_sponzaEntity.AddComponent <CModelComponent>(true, true); m_sponzaEntity.SetWorldPosition(new Vector3(0, -5, -5)); m_sponzaEntity.SetWorldRotation(Quaternion.RotationAxis(Axis.Up, MathUtil.DegreesToRadians(90))); m_sponzaEntity.SetWorldScale(new Vector3(0.03f)); CStaticModelColliderComponent staticModelCollider = m_sponzaEntity.AddComponent <CStaticModelColliderComponent>(true, true); staticModelCollider.ModelAsset = sponzaAsset; modelComponent.Model = sponzaAsset; m_sponzaEntity.IsPhysicsStatic = true; m_sponzaEntity.IsPhysicsEnabled = true; #endregion CMeshAsset cubeAsset = CImportManager.Instance.MeshImporter.LoadMeshAsync("EngineResources/DefaultMeshes/DefaultCube.obj"); CEntity floorEntity = SpawnEntity <CEntity>(); floorEntity.AddComponent <CSceneComponent>(true, true); CMeshComponent floorMesh = floorEntity.AddComponent <CMeshComponent>(true, true); floorMesh.Mesh = cubeAsset; floorMesh.LocalScale = new Vector3(500, 1, 500); CBoxColliderComponent floorCollider = floorEntity.AddComponent <CBoxColliderComponent>(true, true); floorCollider.Height = 1; floorCollider.Width = 500; floorCollider.Length = 500; floorEntity.SetLocalPosition(new Vector3(0, -15, 0)); floorEntity.IsPhysicsStatic = true; floorEntity.IsPhysicsEnabled = true; floorEntity.PhysicalStatic.Material = new Material(1, 0.8f, 1f); #region LightSetup m_lightEntity = SpawnEntity <CEntity>(); m_lightEntity.AddComponent <CSceneComponent>(true, true); CDirectionalLightComponent directionalLight = m_lightEntity.AddComponent <CDirectionalLightComponent>(true, true); directionalLight.LocalRotation = MathUtilities.CreateLookAtQuaternion(Vector3.Normalize(new Vector3(0.2f, -0.5f, 0.2f)), Axis.Up); directionalLight.LightColor = Color4.White * 0.8f; CSpotLightComponent spotLight = m_lightEntity.AddComponent <CSpotLightComponent>(true, true); spotLight.ConstantAttenuation = 0.01f; spotLight.LinearAttenuation = 0.3f; spotLight.QuadraticAttenuation = 0.0f; spotLight.Enabled = true; spotLight.SpotAngle = MathUtil.DegreesToRadians(30.0f); spotLight.LightColor = new Color4(0.1f, 0.8f, 0.1f, 1.0f); spotLight.Range = 100.0f; Quaternion deltaRotation = Quaternion.RotationAxis(Axis.Right, MathUtil.DegreesToRadians(10)); spotLight.LocalRotation = deltaRotation; spotLight.LocalPosition = new Vector3(0, 1, -4); CPointLightComponent pointLight1 = m_lightEntity.AddComponent <CPointLightComponent>(true, true); pointLight1.ConstantAttenuation = 1; pointLight1.LinearAttenuation = 0.2f; pointLight1.Enabled = true; pointLight1.Range = 100.0f; pointLight1.LightColor = new Color4(0.8f, 0.1f, 0.1f, 1.0f); pointLight1.LocalPosition = new Vector3(0, 0, 3.0f); CPointLightComponent pointLight2 = m_lightEntity.AddComponent <CPointLightComponent>(true, true); pointLight2.ConstantAttenuation = 1; pointLight2.LinearAttenuation = 0.4f; pointLight2.Enabled = true; pointLight2.Range = 100.0f; pointLight2.LightColor = new Color4(0.1f, 0.1f, 0.8f, 1.0f); pointLight2.LocalPosition = new Vector3(0, -3, -8.0f); CAmbientLightComponent ambientLight = m_lightEntity.AddComponent <CAmbientLightComponent>(true, true); ambientLight.LightColor = Color4.White * 0.15f; #endregion }
public CMeshRenderNode(object outer, CMeshAsset meshAsset, CMaterialAsset materialOverride, Transform transform) : base(outer) { m_sourceAsset = meshAsset; m_sourceOverrideMaterial = materialOverride; m_transform = transform; }
public void EditorThread_SetPreviewMesh(CMeshAsset meshAsset, bool bKeepMaterial, bool bZoomToFit = true) { OnEngineThread(() => EngineThread_SetPreviewMesh(meshAsset, bKeepMaterial, bZoomToFit)); }
private void LoadMeshInternal(int meshIndex, CMeshAsset asset, CMeshLoadingJob loadingJob, string assetPath, string nameOverride = null, bool bAlwaysImport = false) { Assimp.Mesh assimpMesh = loadingJob.Scene.Meshes[meshIndex]; // Load texture and material from the file if present //todo henning extract more textures Material material = loadingJob.Scene.Materials[assimpMesh.MaterialIndex]; if (material != null && material.GetMaterialTextureCount(TextureType.Diffuse) > 0) { if (material.GetMaterialTexture(TextureType.Diffuse, 0, out TextureSlot texture)) { if (loadingJob.LoadedMaterials == null || !loadingJob.LoadedMaterials.TryGetValue(material.Name, out CMaterialAsset materialAsset)) { materialAsset = new CMaterialAsset(); loadingJob.LoadedMaterials?.Add(material.Name, materialAsset); // Make sure we only load each referenced texture once if (loadingJob.LoadedTextures == null || !loadingJob.LoadedTextures.TryGetValue(texture.FilePath, out CTextureAsset textureAsset)) { textureAsset = CImportManager.Instance.TextureImporter.ImportTextureAsync(loadingJob.BasePath + "\\" + texture.FilePath, assetPath + "Textures/"); loadingJob.LoadedTextures?.Add(texture.FilePath, textureAsset); } SShaderParameter textureParameter = new SShaderParameter() { parameterData = new CAssetReference <CTextureAsset>(textureAsset), parameterType = EShaderParameterType.Texture }; materialAsset.MaterialParameters.Add(new SMaterialParameterEntry(new SHashedName("DiffuseTexture"), textureParameter)); materialAsset.Name = material.Name; if (CAssetRegistry.Instance.RequestRegisterAsset(materialAsset, assetPath + "Materials/", out CMaterialAsset existingMaterial)) { existingMaterial.WaitUntilLoaded(); existingMaterial.CopyFrom(existingMaterial); } materialAsset.LoadFinished(); } asset.MaterialAsset = materialAsset; } } bool hasTexCoords = assimpMesh.HasTextureCoords(0); bool hasColors = assimpMesh.HasVertexColors(0); bool hasNormals = assimpMesh.HasNormals; bool hasTangents = assimpMesh.Tangents != null && assimpMesh.Tangents.Count > 0; bool hasBiTangents = assimpMesh.BiTangents != null && assimpMesh.BiTangents.Count > 0; switch (assimpMesh.PrimitiveType) { case PrimitiveType.Point: asset.PrimitiveTopology = PrimitiveTopology.PointList; break; case PrimitiveType.Line: asset.PrimitiveTopology = PrimitiveTopology.LineList; break; case PrimitiveType.Triangle: asset.PrimitiveTopology = PrimitiveTopology.TriangleList; break; default: throw new ArgumentOutOfRangeException("Primtive Type not supported: " + assimpMesh.PrimitiveType.ToString()); } asset.FaceCount = assimpMesh.FaceCount; asset.VertexData = new SVertexInfo[assimpMesh.VertexCount]; Vector3 boundingBoxMin = new Vector3(1e10f, 1e10f, 1e10f); Vector3 boundingBoxMax = new Vector3(-1e10f, -1e10f, -1e10f); for (int i = 0; i < assimpMesh.VertexCount; i++) { SVertexInfo vertexInfo = new SVertexInfo(); vertexInfo.position = FromAssimpVector(assimpMesh.Vertices[i]); boundingBoxMin.X = Math.Min(vertexInfo.position.X, boundingBoxMin.X); boundingBoxMin.Y = Math.Min(vertexInfo.position.Y, boundingBoxMin.Y); boundingBoxMin.Z = Math.Min(vertexInfo.position.Z, boundingBoxMin.Z); boundingBoxMax.X = Math.Max(vertexInfo.position.X, boundingBoxMax.X); boundingBoxMax.Y = Math.Max(vertexInfo.position.Y, boundingBoxMax.Y); boundingBoxMax.Z = Math.Max(vertexInfo.position.Z, boundingBoxMax.Z); if (hasColors) { vertexInfo.color = FromAssimpColor(assimpMesh.VertexColorChannels[0][i]); } else { vertexInfo.color = Vector4.One; } if (hasNormals) { vertexInfo.normal = FromAssimpVector(assimpMesh.Normals[i]); } if (hasBiTangents) { vertexInfo.biTangent = FromAssimpVector(assimpMesh.BiTangents[i]); } if (hasTangents) { vertexInfo.tangent = FromAssimpVector(assimpMesh.Tangents[i]); } if (hasTexCoords) { Vector3D assimpTexCoord = assimpMesh.TextureCoordinateChannels[0][i]; vertexInfo.texCoord = new Vector2(assimpTexCoord.X, assimpTexCoord.Y); } asset.VertexData[i] = vertexInfo; } asset.AABBMin = boundingBoxMin; asset.AABBMax = boundingBoxMax; asset.IndexData = assimpMesh.GetIndices(); asset.Name = nameOverride ?? assimpMesh.Name; if (CAssetRegistry.Instance.RequestRegisterAsset(asset, assetPath, out CMeshAsset existingAsset, true)) { existingAsset.WaitUntilLoaded(); asset.CopyFrom(existingAsset); } }