Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
UPBGE: Fix issues on LibFree/LibLoad. (#824)
The issue #805 reported a bug relative to LibLoad and LibFree. This bug is reproduced by using two scenes which both use meshes without material (so using defmaterial) and the first scene LibLoad and merge the second. What is happening is that the new created scene will contain a RAS_MaterialBucket of defmaterial which is also used by the host scene, but defmaterial is not owned by any file as it's a global default material. The technique used by LibFree was to tag all ID structs (data, e.g Mesh, Material, Object) of a Main (the file loaded) and remove them from scenes and users. In the situation of defmaterial, this struct is never tagged and so never removed during LibFree. This resulted in a material always existing but all the light objects used were removed and the function GPU_material_update_lamps called in material preparation before rendering raise an illegal memory access as it was iterating on freed lamps. To solve this issue we have to find a way to remove all game engine data that were created during the conversion of a libloaded scene. And the minor task is avoiding end up with only a part of scene materials using all present lights. The first point is solved by the introduction of a resource base class: BL_Resource. The goal of this class is to store an identifier of the library source of converted data. This identifier is opaque type Bl_Resource::Library and the function BL_Resource::Belong(Library) returns true when the passed library identifier match the one of the resource. The classes inheriting from BL_Resource are: - BL_ConvertObjectInfo - KX_Mesh - KX_BlenderMaterial - BL_ActionData All these resource types are registered in BL_SceneConverter where all registering function set the library identifier from the one passed to BL_SceneConverter constructor. From LinkBlendFile, ConvertMeshSpecial and ConvertScene(KX_Scene *scene) (the functions creating a scene converter) BL_SceneConverter is created using as library identifier the Main pointer of the current file or the loaded file, this way we also ensure that all linked data of a file will be owned by the same library. Other than that the loading changed by the call of the function ReloadShaders to reload all shaders of a merged scene: the new and old shaders, to benefit of all existing lights. Concerning LibFree, the first modification is to delay the free to the end of the frame instead doing it instantly. To achieve it, FreeBlendFile(const std::string& path) stores the library path to free in m_freeQueue if the library exists and the function ProcessScheduledLibraries process the merging of the libloads and the free of libraries, this final function is called in KX_KetsjiEngine::NextFrame at the end of each logic frame. The actual library free takes place in FreeBlendFileData. It iterates over all scenes and objects, if the object convert object info belongs to the free library the object is removed else KX_GameObject::RemoveResources is called. Finally the materials, meshes and actions of the library are removed from scene data slots (m_sceneSlots). KX_GameObject::RemoveResources is removing all the meshes that belong to the library or using materials from the library, and do the same for actions currently played. Previously BL_ActionManager was also impacted by LibFree as it was using bAction, now the actuator is using a action name to remove this complexity when freeing an action. Some modifications were introduced to ease the libfree. The class BL_ActionData is used to wrap bAction and link the BL_ScalarInterpolator of the action. All the actions are converted and registered during scene conversion as the cost is negligeable. When a RAS_Texture is free (indirectly by material free while lib free) if the renderer is non null, then the texture unregister itself from the renderer, this mechanism of texture users is near to be obsolete. Shader are now recompiled when merging and freeing a library to ensure that the lights are properly used, the function BL_Covnerter::ReloadShaders is dedicated for and call KX_BlenderMaterial::ReloadMaterial that can reload the shader or create a new one if it wasn't initialized. While reviewing and testing #805, two bugs were noticed. First the animations were not merged in the targeted scene, second the textures could be initialized in the conversion thread whithout opengl context. The first report is fixed by in case of scenes merging creating a converter which aim the conversion of animations of all scenes to merge, the function BL_ConvertActions is called with this converter and convert all actions from a library. The second issue is resolved by moving the call to InitTextures in KX_BlenderMaterial::ReloadShader which is the only place called synchronously during material conversion. Fix issue #805.
- Loading branch information
1 parent
e9b0780
commit b225cb5
Showing
48 changed files
with
873 additions
and
641 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
* ***** BEGIN GPL LICENSE BLOCK ***** | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version 2 | ||
* of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
* | ||
* Contributor(s): Tristan Porteries. | ||
* | ||
* ***** END GPL LICENSE BLOCK ***** | ||
*/ | ||
|
||
/** \file CM_List.h | ||
* \ingroup common | ||
*/ | ||
|
||
#ifndef __CM_LIST_H__ | ||
#define __CM_LIST_H__ | ||
|
||
#include <map> | ||
#include <unordered_map> | ||
|
||
template <class Item, class Key, class ... Args> | ||
inline const Item& CM_MapGetItemNoInsert(const std::map<Key, Item, Args ...>& map, const Key& key, const Item defaultItem = nullptr) | ||
{ | ||
const typename std::map<Key, Item, Args ...>::iterator it = map.find(key); | ||
if (it != map.end()) { | ||
return it->second; | ||
} | ||
return defaultItem; | ||
} | ||
|
||
template <class Item, class Key, class ... Args> | ||
inline const Item& CM_MapGetItemNoInsert(const std::unordered_map<Key, Item, Args ...>& map, const Key& key, const Item defaultItem = nullptr) | ||
{ | ||
const typename std::map<Key, Item, Args ...>::iterator it = map.find(key); | ||
if (it != map.end()) { | ||
return it->second; | ||
} | ||
return defaultItem; | ||
} | ||
|
||
template <class Map, class Item> | ||
inline bool CM_MapRemoveIfItemFound(Map& map, const Item& item) | ||
{ | ||
bool found = false; | ||
for (typename Map::iterator it = map.begin(); it != map.end();) { | ||
if (it->second == item) { | ||
it = map.erase(it); | ||
found = true; | ||
} | ||
else { | ||
++it; | ||
} | ||
} | ||
|
||
return found; | ||
} | ||
|
||
#endif // __CM_LIST_H__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,7 @@ set(SRC | |
CM_Clock.h | ||
CM_Format.h | ||
CM_List.h | ||
CM_Map.h | ||
CM_Message.h | ||
CM_RefCount.h | ||
CM_Template.h | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#include "BL_ActionData.h" | ||
|
||
extern "C" { | ||
# include "DNA_action_types.h" | ||
# include "DNA_anim_types.h" | ||
# include "BKE_fcurve.h" | ||
} | ||
|
||
BL_ActionData::BL_ActionData(bAction *action) | ||
:m_action(action) | ||
{ | ||
for (FCurve *fcu = (FCurve *)action->curves.first; fcu; fcu = fcu->next) { | ||
if (fcu->rna_path) { | ||
m_interpolators.emplace_back(fcu); | ||
} | ||
} | ||
} | ||
|
||
std::string BL_ActionData::GetName() const | ||
{ | ||
return m_action->id.name + 2; | ||
} | ||
|
||
bAction *BL_ActionData::GetAction() const | ||
{ | ||
return m_action; | ||
} | ||
|
||
BL_ScalarInterpolator *BL_ActionData::GetScalarInterpolator(const std::string& rna_path, int array_index) | ||
{ | ||
for (BL_ScalarInterpolator &interp : m_interpolators) { | ||
FCurve *fcu = interp.GetFCurve(); | ||
if (array_index == fcu->array_index && rna_path == fcu->rna_path) { | ||
return &interp; | ||
} | ||
} | ||
return nullptr; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#ifndef __BL_ACTION_DATA_H__ | ||
#define __BL_ACTION_DATA_H__ | ||
|
||
#include "BL_Resource.h" | ||
#include "BL_ScalarInterpolator.h" | ||
|
||
#include <string> | ||
|
||
struct bAction; | ||
|
||
/** Data related to a blender animation. | ||
*/ | ||
class BL_ActionData : public BL_Resource | ||
{ | ||
private: | ||
/// The blender action. | ||
bAction *m_action; | ||
/// The interpolators for each curve (FCurve) of the action. | ||
std::vector<BL_ScalarInterpolator> m_interpolators; | ||
|
||
public: | ||
BL_ActionData(bAction *action); | ||
~BL_ActionData() = default; | ||
|
||
std::string GetName() const; | ||
bAction *GetAction() const; | ||
|
||
BL_ScalarInterpolator *GetScalarInterpolator(const std::string& rna_path, int array_index); | ||
}; | ||
|
||
#endif // __BL_ACTION_DATA_H__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include "BL_ConvertObjectInfo.h" | ||
|
||
BL_ConvertObjectInfo::BL_ConvertObjectInfo(Object *blendobj) | ||
:m_blenderObject(blendobj) | ||
{ | ||
} |
Oops, something went wrong.