Exemplo n.º 1
0
        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;
            }
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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;
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        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);
            });
        }
Exemplo n.º 6
0
        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();
            }
        }
Exemplo n.º 7
0
        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);
        }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 9
0
        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
        }
Exemplo n.º 10
0
 public CMeshRenderNode(object outer, CMeshAsset meshAsset, CMaterialAsset materialOverride, Transform transform) : base(outer)
 {
     m_sourceAsset            = meshAsset;
     m_sourceOverrideMaterial = materialOverride;
     m_transform = transform;
 }
Exemplo n.º 11
0
 public void EditorThread_SetPreviewMesh(CMeshAsset meshAsset, bool bKeepMaterial, bool bZoomToFit = true)
 {
     OnEngineThread(() => EngineThread_SetPreviewMesh(meshAsset, bKeepMaterial, bZoomToFit));
 }
Exemplo n.º 12
0
        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);
            }
        }