HSpriteTexture BuiltinEditorResources::getGUIIcon(const String& name) const { Path texturePath = EditorIconSpritesFolder; texturePath.append("sprite_" + name + ".asset"); return gResources().load<SpriteTexture>(texturePath); }
HShader BuiltinResources::getShader(const Path& path) const { Path programPath = mEngineShaderFolder; programPath.append(path); programPath.setExtension(programPath.getExtension() + ".asset"); return gResources().load<Shader>(programPath); }
HTexture loadTexture(const Path& path, bool isSRGB, bool isCubemap, bool isHDR) { Path assetPath = path; assetPath.setExtension(path.getExtension() + ".asset"); HTexture texture = gResources().load<Texture>(assetPath); if (texture == nullptr) // Texture file doesn't exist, import from the source file. { // When importing you may specify optional import options that control how is the asset imported. SPtr<ImportOptions> textureImportOptions = Importer::instance().createImportOptions(path); // rtti_is_of_type checks if the import options are of valid type, in case the provided path is pointing to a // non-texture resource. This is similar to dynamic_cast but uses Banshee internal RTTI system for type checking. if (rtti_is_of_type<TextureImportOptions>(textureImportOptions)) { TextureImportOptions* importOptions = static_cast<TextureImportOptions*>(textureImportOptions.get()); // We want maximum number of mipmaps to be generated importOptions->setGenerateMipmaps(true); // If the texture is in sRGB space the system needs to know about it importOptions->setSRGB(isSRGB); // Ensures we can save the texture contents importOptions->setCPUCached(true); // Import as cubemap if needed importOptions->setIsCubemap(isCubemap); // If importing as cubemap, assume source is a panorama importOptions->setCubemapSourceType(CubemapSourceType::Cylindrical); // Importing using a HDR format if requested if (isHDR) importOptions->setFormat(PF_RG11B10F); } // Import texture with specified import options texture = gImporter().import<Texture>(path, textureImportOptions); // Save for later use, so we don't have to import on the next run. gResources().save(texture, assetPath, true); } return texture; }
void PrefabUtility::recordPrefabDiff(const HSceneObject& sceneObject) { HSceneObject topLevelObject = sceneObject; while (topLevelObject != nullptr) { if (!topLevelObject->mPrefabLinkUUID.empty()) break; if (topLevelObject->mParent != nullptr) topLevelObject = topLevelObject->mParent; else topLevelObject = nullptr; } if (topLevelObject == nullptr) topLevelObject = sceneObject; Stack<HSceneObject> todo; todo.push(topLevelObject); while (!todo.empty()) { HSceneObject current = todo.top(); todo.pop(); if (!current->mPrefabLinkUUID.empty()) { current->mPrefabDiff = nullptr; HPrefab prefabLink = static_resource_cast<Prefab>(gResources().loadFromUUID(current->mPrefabLinkUUID, false, false)); if (prefabLink.isLoaded(false)) current->mPrefabDiff = PrefabDiff::create(prefabLink->_getRoot(), current->getHandle()); } UINT32 childCount = current->getNumChildren(); for (UINT32 i = 0; i < childCount; i++) { HSceneObject child = current->getChild(i); todo.push(child); } } gResources().unloadAllUnused(); }
HSpriteTexture SpriteTexture::create(const HTexture& texture) { SPtr<SpriteTexture> texturePtr = bs_core_ptr<SpriteTexture> (new (bs_alloc<SpriteTexture>()) SpriteTexture(Vector2(0.0f, 0.0f), Vector2(1.0f, 1.0f), texture)); texturePtr->_setThisPtr(texturePtr); texturePtr->initialize(); return static_resource_cast<SpriteTexture>(gResources()._createResourceHandle(texturePtr)); }
HSpriteTexture SpriteTexture::create(const Vector2& uvOffset, const Vector2& uvScale, const HTexture& texture) { SPtr<SpriteTexture> texturePtr = bs_core_ptr<SpriteTexture> (new (bs_alloc<SpriteTexture>()) SpriteTexture(uvOffset, uvScale, texture)); texturePtr->_setThisPtr(texturePtr); texturePtr->initialize(); return static_resource_cast<SpriteTexture>(gResources()._createResourceHandle(texturePtr)); }
HManagedResource ManagedResource::create(MonoObject* managedResource) { SPtr<ManagedResource> newRes = bs_core_ptr<ManagedResource>(new (bs_alloc<ManagedResource>()) ManagedResource(managedResource)); newRes->_setThisPtr(newRes); newRes->initialize(); HManagedResource handle = static_resource_cast<ManagedResource>(gResources()._createResourceHandle(newRes)); newRes->setHandle(managedResource, handle); return handle; }
HPrefab Prefab::create(const HSceneObject& sceneObject) { SPtr<Prefab> newPrefab = createEmpty(); newPrefab->initialize(sceneObject); HPrefab handle = static_resource_cast<Prefab>(gResources()._createResourceHandle(newPrefab)); newPrefab->mUUID = handle.getUUID(); sceneObject->mPrefabLinkUUID = newPrefab->mUUID; newPrefab->_getRoot()->mPrefabLinkUUID = newPrefab->mUUID; return handle; }
HShader BuiltinEditorResources::getShader(const String& name) const { Path programPath = EditorShaderFolder; programPath.append(name + ".asset"); HShader shader = gResources().load<Shader>(programPath); #if BS_DEBUG_MODE BuiltinResourcesHelper::verifyAndReportShader(shader); #endif return shader; }
HPrefab Prefab::create(const HSceneObject& sceneObject, bool isScene) { SPtr<Prefab> newPrefab = createEmpty(); newPrefab->mIsScene = isScene; PrefabUtility::clearPrefabIds(sceneObject, true, false); newPrefab->initialize(sceneObject); HPrefab handle = static_resource_cast<Prefab>(gResources()._createResourceHandle(newPrefab)); newPrefab->mUUID = handle.getUUID(); sceneObject->mPrefabLinkUUID = newPrefab->mUUID; newPrefab->_getRoot()->mPrefabLinkUUID = newPrefab->mUUID; return handle; }
HTexture BuiltinResources::getTexture(BuiltinTexture type) { Path texturePath = Paths::getDataPath(); texturePath.append(TEXTURE_FOLDER); switch (type) { case BuiltinTexture::Black: texturePath.append(TextureBlackFile); break; case BuiltinTexture::White: texturePath.append(TextureWhiteFile); break; case BuiltinTexture::Normal: texturePath.append(TextureNormalFile); break; } return gResources().load<Texture>(texturePath); }
void PrefabUtility::revertToPrefab(const HSceneObject& so) { String prefabLinkUUID = so->getPrefabLink(); HPrefab prefabLink = static_resource_cast<Prefab>(gResources().loadFromUUID(prefabLinkUUID, false, false)); if (prefabLink == nullptr) return; // Save IDs, destroy original, create new, restore IDs SceneObjectProxy soProxy; UnorderedMap<UINT32, GameObjectInstanceDataPtr> linkedInstanceData; recordInstanceData(so, soProxy, linkedInstanceData); HSceneObject parent = so->getParent(); // This will destroy the object but keep it in the parent's child list HSceneObject currentSO = so; so->destroyInternal(currentSO, true); HSceneObject newInstance = prefabLink->instantiate(); newInstance->mParent = parent; restoreLinkedInstanceData(newInstance, soProxy, linkedInstanceData); }
HGUISkin GUISkin::create() { SPtr<GUISkin> newSkin = _createPtr(); return static_resource_cast<GUISkin>(gResources()._createResourceHandle(newSkin)); }
BuiltinEditorResources::BuiltinEditorResources() { // Set up paths BuiltinRawDataFolder = gEditorApplication().getDataPath() + "Raw/"; EditorRawSkinFolder = BuiltinRawDataFolder + SkinFolder; EditorRawIconsFolder = BuiltinRawDataFolder + IconFolder; EditorRawShaderFolder = BuiltinRawDataFolder + ShaderFolder; EditorRawShaderIncludeFolder = BuiltinRawDataFolder + ShaderIncludeFolder; BuiltinDataFolder = gEditorApplication().getDataPath(); EditorSkinFolder = BuiltinDataFolder + SkinFolder; EditorSkinSpritesFolder = EditorSkinFolder + SpriteSubFolder; EditorIconFolder = BuiltinDataFolder + IconFolder; EditorIconSpritesFolder = EditorIconFolder + SpriteSubFolder; EditorShaderFolder = BuiltinDataFolder + ShaderFolder; EditorShaderIncludeFolder = BuiltinDataFolder + ShaderIncludeFolder; ResourceManifestPath = BuiltinDataFolder + "ResourceManifest.asset"; // Update from raw assets if needed if (FileSystem::exists(BuiltinRawDataFolder)) { time_t lastUpdateTime; UINT32 modifications = BuiltinResourcesHelper::checkForModifications(BuiltinRawDataFolder, BuiltinDataFolder + "Timestamp.asset", lastUpdateTime); // Check if manifest needs to be rebuilt if (modifications == 0 && !FileSystem::exists(ResourceManifestPath)) modifications = 1; if (modifications > 0) { bool forceReimport = modifications == 2; SPtr<ResourceManifest> oldResourceManifest; if (!forceReimport && FileSystem::exists(ResourceManifestPath)) { oldResourceManifest = ResourceManifest::load(ResourceManifestPath, BuiltinDataFolder); if (oldResourceManifest != nullptr) gResources().registerResourceManifest(oldResourceManifest); } if (oldResourceManifest) mResourceManifest = oldResourceManifest; else { mResourceManifest = ResourceManifest::create("BuiltinResources"); gResources().registerResourceManifest(mResourceManifest); } preprocess(modifications == 2, lastUpdateTime); BuiltinResourcesHelper::writeTimestamp(BuiltinDataFolder + "Timestamp.asset"); ResourceManifest::save(mResourceManifest, ResourceManifestPath, BuiltinDataFolder); } } // Load manifest if (mResourceManifest == nullptr) { if (FileSystem::exists(ResourceManifestPath)) mResourceManifest = ResourceManifest::load(ResourceManifestPath, BuiltinDataFolder); if (mResourceManifest == nullptr) mResourceManifest = ResourceManifest::create("BuiltinResources"); gResources().registerResourceManifest(mResourceManifest); } // Load basic resources mShaderDockOverlay = getShader(ShaderDockOverlayFile); mShaderSceneGrid = getShader(ShaderSceneGridFile); mShaderPicking[(int)CULL_NONE] = getShader(ShaderPickingCullNoneFile); mShaderPicking[(int)CULL_CLOCKWISE] = getShader(ShaderPickingCullCWFile); mShaderPicking[(int)CULL_COUNTERCLOCKWISE] = getShader(ShaderPickingCullCCWFile); mShaderPickingAlpha[(int)CULL_NONE] = getShader(ShaderPickingAlphaCullNoneFile); mShaderPickingAlpha[(int)CULL_CLOCKWISE] = getShader(ShaderPickingAlphaCullCWFile); mShaderPickingAlpha[(int)CULL_COUNTERCLOCKWISE] = getShader(ShaderPickingAlphaCullCCWFile); mShaderGizmoSolid = getShader(ShaderSolidGizmoFile); mShaderGizmoLine = getShader(ShaderLineGizmoFile); mShaderGizmoWire = getShader(ShaderWireGizmoFile); mShaderGizmoIcon = getShader(ShaderIconGizmoFile); mShaderGizmoPicking = getShader(ShaderGizmoPickingFile); mShaderGizmoAlphaPicking = getShader(ShaderGizmoPickingAlphaFile); mShaderGizmoText = getShader(ShaderTextGizmoFile); mShaderHandleSolid = getShader(ShaderSolidHandleFile); mShaderHandleClearAlpha = getShader(ShaderHandleClearAlphaFile); mShaderHandleLine = getShader(ShaderLineHandleFile); mShaderSelection = getShader(ShaderSelectionFile); mDefaultFont = gResources().load<Font>(BuiltinDataFolder + (DefaultFontFilename + ".asset")); mDefaultAAFont = gResources().load<Font>(BuiltinDataFolder + (DefaultAAFontFilename + ".asset")); mSkin = gResources().load<GUISkin>(BuiltinDataFolder + (GUISkinFile + ".asset")); }
HFont Font::create(const Vector<SPtr<FontBitmap>>& fontData) { SPtr<Font> newFont = _createPtr(fontData); return static_resource_cast<Font>(gResources()._createResourceHandle(newFont)); }
HAnimationClip AnimationClip::create(const SPtr<AnimationCurves>& curves, bool isAdditive, UINT32 sampleRate, const SPtr<RootMotion>& rootMotion) { return static_resource_cast<AnimationClip>(gResources()._createResourceHandle( _createPtr(curves, isAdditive, sampleRate, rootMotion))); }
ResourceListenerManager::ResourceListenerManager() { mResourceLoadedConn = gResources().onResourceLoaded.connect(std::bind(&ResourceListenerManager::onResourceLoaded, this, _1)); mResourceModifiedConn = gResources().onResourceModified.connect(std::bind(&ResourceListenerManager::onResourceModified, this, _1)); }
void BuiltinEditorResources::preprocess(bool forceImport, time_t lastUpdateTime) { Resources::instance().unloadAllUnused(); Path dataListsFilePath = BuiltinRawDataFolder + DATA_LIST_JSON; SPtr<DataStream> dataListStream = FileSystem::openFile(dataListsFilePath); json dataListJSON = json::parse(dataListStream->getAsString().c_str()); json skinJSON = dataListJSON["Skin"]; json iconsJSON = dataListJSON["Icons"]; json includesJSON = dataListJSON["Includes"]; json shadersJSON = dataListJSON["Shaders"]; // Update DataList.json if needed bool updatedDataLists = false; updatedDataLists |= BuiltinResourcesHelper::updateJSON( EditorRawIconsFolder, BuiltinResourcesHelper::AssetType::Sprite, iconsJSON); updatedDataLists |= BuiltinResourcesHelper::updateJSON( EditorRawShaderIncludeFolder, BuiltinResourcesHelper::AssetType::Normal, includesJSON); updatedDataLists |= BuiltinResourcesHelper::updateJSON( EditorRawShaderFolder, BuiltinResourcesHelper::AssetType::Normal, shadersJSON); updatedDataLists |= BuiltinResourcesHelper::updateJSON( EditorRawSkinFolder, BuiltinResourcesHelper::AssetType::Sprite, skinJSON); dataListStream->close(); if (updatedDataLists) { FileSystem::remove(dataListsFilePath); dataListJSON["Skin"] = skinJSON; dataListJSON["Icons"] = iconsJSON; dataListJSON["Includes"] = includesJSON; dataListJSON["Shaders"] = shadersJSON; String jsonString = dataListJSON.dump(4).c_str(); dataListStream = FileSystem::createAndOpenFile(dataListsFilePath); dataListStream->writeString(jsonString); dataListStream->close(); } // If forcing import, clear all data folders since everything will be recreated anyway Path shaderDependenciesFile = BuiltinDataFolder + "ShaderDependencies.json"; if(forceImport) { FileSystem::remove(EditorIconFolder); FileSystem::remove(EditorShaderIncludeFolder); FileSystem::remove(EditorShaderFolder); FileSystem::remove(EditorSkinFolder); FileSystem::remove(shaderDependenciesFile); } // Read shader dependencies JSON json shaderDependenciesJSON; if(FileSystem::exists(shaderDependenciesFile)) { SPtr<DataStream> stream = FileSystem::openFile(shaderDependenciesFile); shaderDependenciesJSON = json::parse(stream->getAsString().c_str()); stream->close(); } // Import icons { BuiltinResourcesHelper::updateManifest( EditorIconFolder, iconsJSON, mResourceManifest, BuiltinResourcesHelper::AssetType::Sprite); Vector<bool> importFlags = BuiltinResourcesHelper::generateImportFlags( iconsJSON, EditorRawIconsFolder, lastUpdateTime, forceImport); BuiltinResourcesHelper::importAssets( iconsJSON, importFlags, EditorRawIconsFolder, EditorIconFolder, mResourceManifest, BuiltinResourcesHelper::AssetType::Sprite); } // Import shaders { BuiltinResourcesHelper::updateManifest( EditorShaderIncludeFolder, includesJSON, mResourceManifest, BuiltinResourcesHelper::AssetType::Normal); BuiltinResourcesHelper::updateManifest( EditorShaderFolder, shadersJSON, mResourceManifest, BuiltinResourcesHelper::AssetType::Normal); Vector<bool> includeImportFlags = BuiltinResourcesHelper::generateImportFlags( includesJSON, EditorRawShaderIncludeFolder, lastUpdateTime, forceImport); Vector<bool> shaderImportFlags = BuiltinResourcesHelper::generateImportFlags( shadersJSON, EditorRawShaderFolder, lastUpdateTime, forceImport, &shaderDependenciesJSON, EditorRawShaderIncludeFolder); // Hidden dependency: Includes must be imported before shaders, but import flags for shaders must be generated // before includes are imported, since the process checks if imports changed BuiltinResourcesHelper::importAssets( includesJSON, includeImportFlags, EditorRawShaderIncludeFolder, EditorShaderIncludeFolder, mResourceManifest, BuiltinResourcesHelper::AssetType::Normal); BuiltinResourcesHelper::importAssets( shadersJSON, shaderImportFlags, EditorRawShaderFolder, EditorShaderFolder, mResourceManifest, BuiltinResourcesHelper::AssetType::Normal, &shaderDependenciesJSON); } // Import GUI sprites { BuiltinResourcesHelper::updateManifest( EditorSkinFolder, skinJSON, mResourceManifest, BuiltinResourcesHelper::AssetType::Sprite); Vector<bool> includeImportFlags = BuiltinResourcesHelper::generateImportFlags( skinJSON, EditorRawSkinFolder, lastUpdateTime, forceImport); BuiltinResourcesHelper::importAssets( skinJSON, includeImportFlags, EditorRawSkinFolder, EditorSkinFolder, mResourceManifest, BuiltinResourcesHelper::AssetType::Sprite); } // Update shader dependencies JSON { String jsonString = shaderDependenciesJSON.dump(4).c_str(); dataListStream = FileSystem::createAndOpenFile(shaderDependenciesFile); dataListStream->writeString(jsonString); dataListStream->close(); } // Import fonts BuiltinResourcesHelper::importFont( BuiltinRawDataFolder + DefaultFontFilename, DefaultFontFilename, BuiltinDataFolder, { DefaultFontSize }, true, UUID("6ce69053-00d7-4c60-a229-249b8d8fd60e"), mResourceManifest); BuiltinResourcesHelper::importFont( BuiltinRawDataFolder + DefaultFontFilename, DefaultAAFontFilename, BuiltinDataFolder, { TitleFontSize }, true, UUID("10999b74-d976-4116-9f72-21e489a7a8e4"), mResourceManifest); // Import splash screen { Path inputPath = BuiltinRawDataFolder + String(SplashScreenName); Path outputPath = BuiltinDataFolder + (String(SplashScreenName) + ".asset"); auto textureIO = gImporter().createImportOptions<TextureImportOptions>(inputPath); textureIO->setCPUCached(true); textureIO->setGenerateMipmaps(false); HTexture splashTexture = gImporter().import<Texture>(inputPath, textureIO); SPtr<PixelData> splashPixelData = splashTexture->getProperties().allocBuffer(0, 0); splashTexture->readCachedData(*splashPixelData); FileEncoder fe(outputPath); fe.encode(splashPixelData.get()); } // Generate & save GUI skin { SPtr<GUISkin> skin = generateGUISkin(); Path outputPath = BuiltinDataFolder + (GUISkinFile + ".asset"); HResource skinResource = gResources()._createResourceHandle(skin, UUID("ec0ea68d-efa5-4a3b-a6fc-b15aaec9689f")); gResources().save(skinResource, outputPath, true); mResourceManifest->registerResource(skinResource.getUUID(), outputPath); } Resources::instance().unloadAllUnused(); }
HAnimationClip AnimationClip::create(bool isAdditive) { return static_resource_cast<AnimationClip>(gResources()._createResourceHandle( _createPtr(bs_shared_ptr_new<AnimationCurves>(), isAdditive))); }
HAudioClip AudioClip::create(const SPtr<DataStream>& samples, UINT32 streamSize, UINT32 numSamples, const AUDIO_CLIP_DESC& desc) { return static_resource_cast<AudioClip>(gResources()._createResourceHandle(_createPtr(samples, streamSize, numSamples, desc))); }
BuiltinResources::BuiltinResources() { // Set up paths mBuiltinRawDataFolder = Paths::getDataPath() + u8"Raw/"; mBuiltinDataFolder = Paths::getDataPath(); mEngineSkinSpritesFolder = mBuiltinDataFolder + SKIN_FOLDER + SPRITE_FOLDER; mEngineShaderFolder = mBuiltinDataFolder + SHADER_FOLDER; mEngineMeshFolder = mBuiltinDataFolder + MESH_FOLDER; mEngineCursorFolder = mBuiltinDataFolder + CURSOR_FOLDER; ResourceManifestPath = mBuiltinDataFolder + "ResourceManifest.asset"; // Update from raw assets if needed if (FileSystem::exists(mBuiltinRawDataFolder)) { time_t lastUpdateTime; UINT32 modifications = BuiltinResourcesHelper::checkForModifications( mBuiltinRawDataFolder, mBuiltinDataFolder + u8"Timestamp.asset", lastUpdateTime); // Check if manifest needs to be rebuilt if (modifications == 0 && !FileSystem::exists(ResourceManifestPath)) modifications = 1; if (modifications > 0) { bool fullReimport = modifications == 2; SPtr<ResourceManifest> oldResourceManifest; if (!fullReimport && FileSystem::exists(ResourceManifestPath)) { oldResourceManifest = ResourceManifest::load(ResourceManifestPath, mBuiltinDataFolder); if (oldResourceManifest != nullptr) gResources().registerResourceManifest(oldResourceManifest); } if (oldResourceManifest) mResourceManifest = oldResourceManifest; else { mResourceManifest = ResourceManifest::create("BuiltinResources"); gResources().registerResourceManifest(mResourceManifest); } preprocess(fullReimport, lastUpdateTime); BuiltinResourcesHelper::writeTimestamp(mBuiltinDataFolder + u8"Timestamp.asset"); ResourceManifest::save(mResourceManifest, ResourceManifestPath, mBuiltinDataFolder); } } // Load manifest if (mResourceManifest == nullptr) { if (FileSystem::exists(ResourceManifestPath)) mResourceManifest = ResourceManifest::load(ResourceManifestPath, mBuiltinDataFolder); if (mResourceManifest == nullptr) mResourceManifest = ResourceManifest::create("BuiltinResources"); gResources().registerResourceManifest(mResourceManifest); } if (FileSystem::exists(mBuiltinRawDataFolder)) { // Update shader bytecode for the current render backend, if needed const RenderAPIInfo& apiInfo = ct::RenderAPI::instance().getAPIInfo(); bool supportsBytecodeCaching = apiInfo.isFlagSet(RenderAPIFeatureFlag::ByteCodeCaching); if (supportsBytecodeCaching) { Path dataListsFilePath = mBuiltinRawDataFolder + DATA_LIST_JSON; SPtr<DataStream> dataListStream = FileSystem::openFile(dataListsFilePath); if (dataListStream) { json dataListJSON = json::parse(dataListStream->getAsString().c_str()); json shadersJSON = dataListJSON["Shaders"]; for (auto& entry : shadersJSON) { std::string uuidStr = entry["UUID"]; UUID uuid(uuidStr.c_str()); Path filePath; if (!mResourceManifest->uuidToFilePath(uuid, filePath)) continue; BuiltinResourcesHelper::updateShaderBytecode(filePath); } } } } // Load basic resources mShaderSpriteText = getShader(ShaderSpriteTextFile); mShaderSpriteImage = getShader(ShaderSpriteImageAlphaFile); mShaderSpriteNonAlphaImage = getShader(ShaderSpriteImageNoAlphaFile); mShaderSpriteLine = getShader(ShaderSpriteLineFile); mShaderDiffuse = getShader(ShaderDiffuseFile); mShaderTransparent = getShader(ShaderTransparentFile); mShaderParticlesUnlit = getShader(ShaderParticlesUnlitFile); SPtr<PixelData> dummyPixelData = PixelData::create(2, 2, 1, PF_RGBA8); dummyPixelData->setColorAt(Color::Red, 0, 0); dummyPixelData->setColorAt(Color::Red, 0, 1); dummyPixelData->setColorAt(Color::Red, 1, 0); dummyPixelData->setColorAt(Color::Red, 1, 1); mDummyTexture = Texture::create(dummyPixelData); mWhiteSpriteTexture = getSkinTexture(WhiteTex); mDummySpriteTexture = SpriteTexture::create(mDummyTexture); mFont = gResources().load<Font>(mBuiltinDataFolder + (DefaultFontFilename + u8".asset")); mSkin = gResources().load<GUISkin>(mBuiltinDataFolder + (GUISkinFile + u8".asset")); mEmptySkin = GUISkin::create(); /************************************************************************/ /* CURSOR */ /************************************************************************/ HTexture cursorArrowTex = getCursorTexture(CursorArrowTex); HTexture cursorArrowDragTex = getCursorTexture(CursorArrowDragTex); HTexture cursorArrowLeftRightTex = getCursorTexture(CursorArrowLeftRightTex); HTexture cursorIBeamTex = getCursorTexture(CursorIBeamTex); HTexture cursorDenyTex = getCursorTexture(CursorDenyTex); HTexture cursorWaitTex = getCursorTexture(CursorWaitTex); HTexture cursorSizeNESWTex = getCursorTexture(CursorSizeNESWTex); HTexture cursorSizeNSTex = getCursorTexture(CursorSizeNSTex); HTexture cursorSizeNWSETex = getCursorTexture(CursorSizeNWSETex); HTexture cursorSizeWETex = getCursorTexture(CursorSizeWETex); mCursorArrow = cursorArrowTex->getProperties().allocBuffer(0, 0); cursorArrowTex->readData(mCursorArrow); mCursorArrowDrag = cursorArrowDragTex->getProperties().allocBuffer(0, 0); cursorArrowDragTex->readData(mCursorArrowDrag); mCursorArrowLeftRight = cursorArrowLeftRightTex->getProperties().allocBuffer(0, 0); cursorArrowLeftRightTex->readData(mCursorArrowLeftRight); mCursorIBeam = cursorIBeamTex->getProperties().allocBuffer(0, 0); cursorIBeamTex->readData(mCursorIBeam); mCursorDeny = cursorDenyTex->getProperties().allocBuffer(0, 0); cursorDenyTex->readData(mCursorDeny); mCursorWait = cursorWaitTex->getProperties().allocBuffer(0, 0); cursorWaitTex->readData(mCursorWait); mCursorSizeNESW = cursorSizeNESWTex->getProperties().allocBuffer(0, 0); cursorSizeNESWTex->readData(mCursorSizeNESW); mCursorSizeNS = cursorSizeNSTex->getProperties().allocBuffer(0, 0); cursorSizeNSTex->readData(mCursorSizeNS); mCursorSizeNWSE = cursorSizeNWSETex->getProperties().allocBuffer(0, 0); cursorSizeNWSETex->readData(mCursorSizeNWSE); mCursorSizeWE = cursorSizeWETex->getProperties().allocBuffer(0, 0); cursorSizeWETex->readData(mCursorSizeWE); /************************************************************************/ /* ICON */ /************************************************************************/ Path iconPath = mBuiltinDataFolder + ICON_FOLDER; iconPath.append(String(IconTextureName) + u8".asset"); HTexture iconTex = gResources().load<Texture>(iconPath); mFrameworkIcon = iconTex->getProperties().allocBuffer(0, 0); iconTex->readData(mFrameworkIcon); gCoreThread().submit(true); }
HSpriteTexture SpriteTexture::create(const HTexture& texture) { SPtr<SpriteTexture> texturePtr = _createPtr(texture); return static_resource_cast<SpriteTexture>(gResources()._createResourceHandle(texturePtr)); }
void BuiltinResources::preprocess(bool forceImport, time_t lastUpdateTime) { // Hidden dependency: Textures need to be generated before shaders as they may use the default textures generateTextures(); Path dataListsFilePath = mBuiltinRawDataFolder + DATA_LIST_JSON; SPtr<DataStream> dataListStream = FileSystem::openFile(dataListsFilePath); json dataListJSON = json::parse(dataListStream->getAsString().c_str()); json skinJSON = dataListJSON["Skin"]; json cursorsJSON = dataListJSON["Cursors"]; json iconsJSON = dataListJSON["Icons"]; json includesJSON = dataListJSON["Includes"]; json shadersJSON = dataListJSON["Shaders"]; Path rawSkinFolder = mBuiltinRawDataFolder + SKIN_FOLDER; Path rawCursorFolder = mBuiltinRawDataFolder + CURSOR_FOLDER; Path rawIconFolder = mBuiltinRawDataFolder + ICON_FOLDER; Path rawShaderFolder = mBuiltinRawDataFolder + SHADER_FOLDER; Path rawShaderIncludeFolder = mBuiltinRawDataFolder + SHADER_INCLUDE_FOLDER; // Update DataList.json if needed bool updatedDataLists = false; updatedDataLists |= BuiltinResourcesHelper::updateJSON( rawCursorFolder, BuiltinResourcesHelper::AssetType::Normal, cursorsJSON); updatedDataLists |= BuiltinResourcesHelper::updateJSON( rawIconFolder, BuiltinResourcesHelper::AssetType::Normal, iconsJSON); updatedDataLists |= BuiltinResourcesHelper::updateJSON( rawShaderIncludeFolder, BuiltinResourcesHelper::AssetType::Normal, includesJSON); updatedDataLists |= BuiltinResourcesHelper::updateJSON( rawShaderFolder, BuiltinResourcesHelper::AssetType::Normal, shadersJSON); updatedDataLists |= BuiltinResourcesHelper::updateJSON( rawSkinFolder, BuiltinResourcesHelper::AssetType::Sprite, skinJSON); dataListStream->close(); if(updatedDataLists) { FileSystem::remove(dataListsFilePath); dataListJSON["Skin"] = skinJSON; dataListJSON["Cursors"] = cursorsJSON; dataListJSON["Icons"] = iconsJSON; dataListJSON["Includes"] = includesJSON; dataListJSON["Shaders"] = shadersJSON; String jsonString = dataListJSON.dump(4).c_str(); dataListStream = FileSystem::createAndOpenFile(dataListsFilePath); dataListStream->writeString(jsonString); dataListStream->close(); } Path skinFolder = mBuiltinDataFolder + SKIN_FOLDER; Path iconFolder = mBuiltinDataFolder + ICON_FOLDER; Path shaderIncludeFolder = mBuiltinDataFolder + SHADER_INCLUDE_FOLDER; Path shaderDependenciesFile = mBuiltinDataFolder + "ShaderDependencies.json"; // If forcing import, clear all data folders since everything will be recreated anyway if(forceImport) { FileSystem::remove(mEngineCursorFolder); FileSystem::remove(iconFolder); FileSystem::remove(shaderIncludeFolder); FileSystem::remove(mEngineShaderFolder); FileSystem::remove(skinFolder); FileSystem::remove(shaderDependenciesFile); } // Read shader dependencies JSON json shaderDependenciesJSON; if(FileSystem::exists(shaderDependenciesFile)) { SPtr<DataStream> stream = FileSystem::openFile(shaderDependenciesFile); shaderDependenciesJSON = json::parse(stream->getAsString().c_str()); stream->close(); } // Import cursors { BuiltinResourcesHelper::updateManifest( mEngineCursorFolder, cursorsJSON, mResourceManifest, BuiltinResourcesHelper::AssetType::Normal); Vector<bool> importFlags = BuiltinResourcesHelper::generateImportFlags( cursorsJSON, rawCursorFolder, lastUpdateTime, forceImport); BuiltinResourcesHelper::importAssets( cursorsJSON, importFlags, rawCursorFolder, mEngineCursorFolder, mResourceManifest, BuiltinResourcesHelper::AssetType::Normal); } // Import icons { BuiltinResourcesHelper::updateManifest( iconFolder, iconsJSON, mResourceManifest, BuiltinResourcesHelper::AssetType::Normal); Vector<bool> importFlags = BuiltinResourcesHelper::generateImportFlags( iconsJSON, rawIconFolder, lastUpdateTime, forceImport); BuiltinResourcesHelper::importAssets( iconsJSON, importFlags, rawIconFolder, iconFolder, mResourceManifest, BuiltinResourcesHelper::AssetType::Normal); } // Import shaders { BuiltinResourcesHelper::updateManifest( shaderIncludeFolder, includesJSON, mResourceManifest, BuiltinResourcesHelper::AssetType::Normal); BuiltinResourcesHelper::updateManifest( mEngineShaderFolder, shadersJSON, mResourceManifest, BuiltinResourcesHelper::AssetType::Normal); Vector<bool> includeImportFlags = BuiltinResourcesHelper::generateImportFlags( includesJSON, rawShaderIncludeFolder, lastUpdateTime, forceImport); Vector<bool> shaderImportFlags = BuiltinResourcesHelper::generateImportFlags( shadersJSON, rawShaderFolder, lastUpdateTime, forceImport, &shaderDependenciesJSON, rawShaderIncludeFolder); // Hidden dependency: Includes must be imported before shaders, but import flags for shaders must be generated // before includes are imported, since the process checks if imports changed BuiltinResourcesHelper::importAssets( includesJSON, includeImportFlags, rawShaderIncludeFolder, shaderIncludeFolder, mResourceManifest, BuiltinResourcesHelper::AssetType::Normal, nullptr, true); BuiltinResourcesHelper::importAssets( shadersJSON, shaderImportFlags, rawShaderFolder, mEngineShaderFolder, mResourceManifest, BuiltinResourcesHelper::AssetType::Normal, &shaderDependenciesJSON, true); } // Import GUI sprites { BuiltinResourcesHelper::updateManifest( skinFolder, skinJSON, mResourceManifest, BuiltinResourcesHelper::AssetType::Sprite); Vector<bool> skinImportFlags = BuiltinResourcesHelper::generateImportFlags( skinJSON, rawSkinFolder, lastUpdateTime, forceImport); BuiltinResourcesHelper::importAssets( skinJSON, skinImportFlags, rawSkinFolder, skinFolder, mResourceManifest, BuiltinResourcesHelper::AssetType::Sprite); } // Update shader dependencies JSON { String jsonString = shaderDependenciesJSON.dump(4).c_str(); dataListStream = FileSystem::createAndOpenFile(shaderDependenciesFile); dataListStream->writeString(jsonString); dataListStream->close(); } // Import font BuiltinResourcesHelper::importFont( mBuiltinRawDataFolder + DefaultFontFilename, DefaultFontFilename, mBuiltinDataFolder, { DefaultFontSize }, false, UUID("c9f08cab-f9c9-47c4-96e0-1066a8d4455b"), mResourceManifest); // Generate & save GUI skin { SPtr<GUISkin> skin = generateGUISkin(); Path outputPath = mBuiltinDataFolder + (GUISkinFile + u8".asset"); HResource skinResource = gResources()._createResourceHandle(skin, UUID("c1bf9a9d-4355-4841-a538-25e67730ec4b")); gResources().save(skinResource, outputPath, true); mResourceManifest->registerResource(skinResource.getUUID(), outputPath); } // Generate & save meshes generateMeshes(); Resources::instance().unloadAllUnused(); }
void BuiltinResources::generateMeshes() { SPtr<VertexDataDesc> vertexDesc = bs_shared_ptr_new<VertexDataDesc>(); vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION); vertexDesc->addVertElem(VET_FLOAT2, VES_TEXCOORD); vertexDesc->addVertElem(VET_FLOAT3, VES_NORMAL); vertexDesc->addVertElem(VET_FLOAT4, VES_TANGENT); vertexDesc->addVertElem(VET_COLOR, VES_COLOR); UINT32 boxNumVertices = 0; UINT32 boxNumIndices = 0; ShapeMeshes3D::getNumElementsAABox(boxNumVertices, boxNumIndices); SPtr<MeshData> boxMeshData = MeshData::create(boxNumVertices, boxNumIndices, vertexDesc); AABox box(Vector3(-0.5f, -0.5f, -0.5f), Vector3(0.5f, 0.5f, 0.5f)); ShapeMeshes3D::solidAABox(box, boxMeshData, 0, 0); SPtr<Mesh> boxMesh = Mesh::_createPtr(RendererMeshData::convert(boxMeshData)); UINT32 sphereNumVertices = 0; UINT32 sphereNumIndices = 0; ShapeMeshes3D::getNumElementsSphere(3, sphereNumVertices, sphereNumIndices); SPtr<MeshData> sphereMeshData = bs_shared_ptr_new<MeshData>(sphereNumVertices, sphereNumIndices, vertexDesc); ShapeMeshes3D::solidSphere(Sphere(Vector3::ZERO, 1.0f), sphereMeshData, 0, 0, 3); SPtr<Mesh> sphereMesh = Mesh::_createPtr(RendererMeshData::convert(sphereMeshData)); UINT32 coneNumVertices = 0; UINT32 coneNumIndices = 0; ShapeMeshes3D::getNumElementsCone(10, coneNumVertices, coneNumIndices); SPtr<MeshData> coneMeshData = bs_shared_ptr_new<MeshData>(coneNumVertices, coneNumIndices, vertexDesc); ShapeMeshes3D::solidCone(Vector3::ZERO, Vector3::UNIT_Y, 1.0f, 1.0f, Vector2::ONE, coneMeshData, 0, 0); SPtr<Mesh> coneMesh = Mesh::_createPtr(RendererMeshData::convert(coneMeshData)); UINT32 cylinderNumVertices = 0; UINT32 cylinderNumIndices = 0; ShapeMeshes3D::getNumElementsCylinder(10, cylinderNumVertices, cylinderNumIndices); SPtr<MeshData> cylinderMeshData = bs_shared_ptr_new<MeshData>(cylinderNumVertices, cylinderNumIndices, vertexDesc); ShapeMeshes3D::solidCylinder(Vector3::ZERO, Vector3::UNIT_Y, 1.0f, 1.0f, Vector2::ONE, cylinderMeshData, 0, 0); SPtr<Mesh> cylinderMesh = Mesh::_createPtr(RendererMeshData::convert(cylinderMeshData)); UINT32 quadNumVertices = 8; UINT32 quadNumIndices = 12; ShapeMeshes3D::getNumElementsQuad(quadNumVertices, quadNumIndices); SPtr<MeshData> quadMeshData = bs_shared_ptr_new<MeshData>(quadNumVertices, quadNumIndices, vertexDesc); std::array<Vector3, 2> axes = {{ Vector3::UNIT_X, Vector3::UNIT_Z }}; std::array<float, 2> sizes = {{ 1.0f, 1.0f }}; Rect3 rect(Vector3::ZERO, axes, sizes); ShapeMeshes3D::solidQuad(rect, quadMeshData, 0, 0); SPtr<Mesh> quadMesh = Mesh::_createPtr(RendererMeshData::convert(quadMeshData)); UINT32 discNumVertices = 0; UINT32 discNumIndices = 0; ShapeMeshes3D::getNumElementsDisc(10, discNumVertices, discNumIndices); SPtr<MeshData> discMeshData = bs_shared_ptr_new<MeshData>(discNumVertices, discNumIndices, vertexDesc); ShapeMeshes3D::solidDisc(Vector3::ZERO, 1.0f, Vector3::UNIT_Y, discMeshData, 0, 0); SPtr<Mesh> discMesh = Mesh::_createPtr(RendererMeshData::convert(discMeshData)); // Save all meshes Path outputDir = mEngineMeshFolder; auto saveMesh = [&](const Path& path, const SPtr<Mesh>& mesh, const String& uuid) { HResource meshResource = gResources()._createResourceHandle(mesh, UUID(uuid)); gResources().save(meshResource, path, true); mResourceManifest->registerResource(meshResource.getUUID(), path); }; Path boxPath = outputDir + MeshBoxFile; saveMesh(boxPath, boxMesh, "bc1d20ca-7fe6-489b-8b5c-dbf798badc95"); Path spherePath = outputDir + MeshSphereFile; saveMesh(spherePath, sphereMesh, "040642f3-04d6-419e-9dba-f7824161c205"); Path conePath = outputDir + MeshConeFile; saveMesh(conePath, coneMesh, "b8cf6db5-1736-47ac-852f-82ecd88b4d46"); Path cylinderPath = outputDir + MeshCylinderFile; saveMesh(cylinderPath, cylinderMesh, "e6b2b797-4e72-7e49-61ba-4e7275bd561d"); Path quadPath = outputDir + MeshQuadFile; saveMesh(quadPath, quadMesh, "06592bf3-f82a-472e-a034-26a98225fbe1"); Path discPath = outputDir + MeshDiscFile; saveMesh(discPath, discMesh, "6f496313-344a-495c-83e8-152e3053c52d"); }
void PrefabUtility::updateFromPrefab(const HSceneObject& so) { HSceneObject topLevelObject = so; while (topLevelObject != nullptr) { if (!topLevelObject->mPrefabLinkUUID.empty()) break; if (topLevelObject->mParent != nullptr) topLevelObject = topLevelObject->mParent; else topLevelObject = nullptr; } Stack<HSceneObject> todo; todo.push(topLevelObject); // Find any prefab instances Vector<HSceneObject> prefabInstanceRoots; while (!todo.empty()) { HSceneObject current = todo.top(); todo.pop(); if (!current->mPrefabLinkUUID.empty()) prefabInstanceRoots.push_back(current); UINT32 childCount = current->getNumChildren(); for (UINT32 i = 0; i < childCount; i++) { HSceneObject child = current->getChild(i); todo.push(child); } } // Stores data about the new prefab instance and its original parent and link id // (as those aren't stored in the prefab diff) struct RestoredPrefabInstance { HSceneObject newInstance; HSceneObject originalParent; SPtr<PrefabDiff> diff; UINT32 originalLinkId; }; Vector<RestoredPrefabInstance> newPrefabInstanceData; // For each prefab instance load its reference prefab from the disk and check if it changed. If it has changed // instantiate the prefab and destroy the current instance. Then apply instance specific changes stored in a // prefab diff, if any, as well as restore the original parent and link id (link id of the root prefab instance // belongs to the parent prefab if any). Finally fix any handles pointing to the old objects so that they now point // to the newly instantiated objects. To the outside world it should be transparent that we just destroyed and then // re-created from scratch the entire hierarchy. // Need to do this bottom up to ensure I don't destroy the parents before children for (auto iter = prefabInstanceRoots.rbegin(); iter != prefabInstanceRoots.rend(); ++iter) { HSceneObject current = *iter; HPrefab prefabLink = static_resource_cast<Prefab>(gResources().loadFromUUID(current->mPrefabLinkUUID, false, false)); if (prefabLink.isLoaded(false) && prefabLink->getHash() != current->mPrefabHash) { // Save IDs, destroy original, create new, restore IDs SceneObjectProxy soProxy; UnorderedMap<UINT32, GameObjectInstanceDataPtr> linkedInstanceData; recordInstanceData(current, soProxy, linkedInstanceData); HSceneObject parent = current->getParent(); SPtr<PrefabDiff> prefabDiff = current->mPrefabDiff; current->destroy(true); HSceneObject newInstance = prefabLink->_clone(); // When restoring instance IDs it is important to make all the new handles point to the old GameObjectInstanceData. // This is because old handles will have different GameObjectHandleData and we have no easy way of accessing it to // change to which GameObjectInstanceData it points. But the GameObjectManager ensures that all handles deserialized // at once (i.e. during the ::instantiate() call above) will share GameObjectHandleData so we can simply replace // to what they point to, affecting all of the handles to that object. (In another words, we can modify the // new handles at this point, but old ones must keep referencing what they already were.) restoreLinkedInstanceData(newInstance, soProxy, linkedInstanceData); restoreUnlinkedInstanceData(newInstance, soProxy); newPrefabInstanceData.push_back({ newInstance, parent, prefabDiff, newInstance->getLinkId() }); } } // Once everything is instantiated, apply diffs, restore old parents & link IDs for root. for (auto& entry : newPrefabInstanceData) { // Diffs must be applied after everything is instantiated and instance data restored since it may contain // game object handles within or external to its prefab instance. if (entry.diff != nullptr) entry.diff->apply(entry.newInstance); entry.newInstance->mPrefabDiff = entry.diff; entry.newInstance->setParent(entry.originalParent, false); entry.newInstance->mLinkId = entry.originalLinkId; } gResources().unloadAllUnused(); }
HShaderInclude ShaderInclude::create(const String& includeString) { return static_resource_cast<ShaderInclude>(gResources()._createResourceHandle(_createPtr(includeString))); }
HSpriteTexture SpriteTexture::create(const Vector2& uvOffset, const Vector2& uvScale, const HTexture& texture) { SPtr<SpriteTexture> texturePtr = _createPtr(uvOffset, uvScale, texture); return static_resource_cast<SpriteTexture>(gResources()._createResourceHandle(texturePtr)); }
HScriptCode ScriptCode::create(const WString& data, bool editorScript) { return static_resource_cast<ScriptCode>(gResources()._createResourceHandle(_createPtr(data, editorScript))); }