3static const int TEXTURE_SIZES[3] = {512, 1024, 2048};
4static const int TEXTURE_IMPORT_SIZES[4] = {-1, 256, 512, 1024};
5static const int SUPER_SAMPLING[3] = {1, 2, 4};
7class ParamEnumTextureSize : array<ref ParamEnum>
11 ParamEnumArray
params =
new ParamEnumArray();
13 for (
int i, max = StaticArray.Length(TEXTURE_SIZES); i < max; i++)
22class ParamEnumTextureImportSize : array<ref ParamEnum>
26 ParamEnumArray
params =
new ParamEnumArray();
30 for (
int i = 1, max = StaticArray.Length(TEXTURE_IMPORT_SIZES); i < max; i++)
39class ParamEnumSuperSampling : array<ref ParamEnum>
43 ParamEnumArray
params =
new ParamEnumArray();
65[
WorkbenchPluginAttribute(name:
"EBT: Bake MLOD", wbModules: {
"ResourceManager" }, resourceTypes: {
"fbx",
"xob" }, awesomeFontCode: 0xf7ec)]
66class BakeMLODPlugin : WorkbenchPlugin
69 protected int m_iNumberOfSamples;
72 protected bool m_bRunInBackground =
true;
75 protected static ref StartBakeDialogXOB s_StartBakeDialogXOB =
new StartBakeDialogXOB(
"Bake XOB MLOD");
77 static ref StartBakeDialogET s_StartBakeDialogET =
new StartBakeDialogET(
"Bake ET MLOD");
79 protected static BakeMLODPlugin s_Instance;
87 static BakeMLODPlugin GetInstance()
92 static bool GetOperatorDescription(StartBakeDialog startBakeDialog,
ResourceName resourceName,
int noOfSamples, out BlenderOperatorDescription operatorDescription)
94 string pathToResourceParam;
95 Workbench.GetAbsolutePath(
resourceName.GetPath(), pathToResourceParam);
98 pathToResourceParam.Replace(
".xob",
".fbx");
100 if (!
FileIO.FileExists(pathToResourceParam))
102 Print(
"Resource couldn't be imported to blender because .fbx file is missing",
LogLevel.WARNING);
107 int textureSize= TEXTURE_SIZES[startBakeDialog.m_iTextureSize];
108 int textureImportSize= TEXTURE_IMPORT_SIZES[startBakeDialog.m_iTextureImportSize];
109 int superSamplingSize = SUPER_SAMPLING[startBakeDialog.m_iSuperSampling];
111 operatorDescription.AddParam(
"file_path", pathToResourceParam);
112 operatorDescription.AddParam(
"clear_color", startBakeDialog.m_ClearColor);
113 operatorDescription.AddParam(
"texture_size", textureSize);
114 operatorDescription.AddParam(
"texture_import_size", textureImportSize);
115 operatorDescription.AddParam(
"cage_extrusion", startBakeDialog.m_fCageExtrusion);
116 operatorDescription.AddParam(
"ray_distance", startBakeDialog.m_fRayDistance);
117 operatorDescription.AddParam(
"skip_interior", startBakeDialog.m_bSkipInterior);
118 operatorDescription.AddParam(
"no_of_samples", noOfSamples);
119 operatorDescription.AddParam(
"fix_ray_miss_type", startBakeDialog.m_eFixRayType);
120 operatorDescription.AddParam(
"fix_ray_miss_extents", startBakeDialog.m_eFixRayExtents);
121 operatorDescription.AddParam(
"super_sampling", superSamplingSize);
124 if (startBakeDialog.Type() == StartBakeDialogXOB)
126 StartBakeDialogXOB dialog = StartBakeDialogXOB.Cast(startBakeDialog);
128 string absTexturePath =
"";
130 if(dialog.m_sTexturePath !=
"")
132 Workbench.GetAbsolutePath(dialog.m_sTexturePath,absTexturePath);
134 operatorDescription.blIDName =
"ebt.bake_workbench_background_xob_mlod";
135 operatorDescription.AddParam(
"re_uv", dialog.m_bReUV);
136 operatorDescription.AddParam(
"skip_transparent", dialog.m_bSkipTransparent);
137 operatorDescription.AddParam(
"create_new_texture", dialog.m_bCreateNewTexture);
138 operatorDescription.AddParam(
"texture_name",dialog.m_sTextureName);
139 operatorDescription.AddParam(
"texture_path",absTexturePath);
144 if (!PrefabImporterBake.GetBaseFBX(
resourceName, baseFbx))
150 operatorDescription.blIDName =
"ebt.bake_workbench_background_et_mlod";
151 operatorDescription.AddParam(
"base_fbx", baseFbx);
152 operatorDescription.AddParam(
"new_texture", StartBakeDialogET.Cast(startBakeDialog).m_sNewTextureName);
161 if (!EBTConfigPlugin.HasBlenderRegistered())
164 StartBakeDialog bakeDialog = s_StartBakeDialogET;
166 if (resource.EndsWith(
".xob") || resource.EndsWith(
".fbx"))
167 bakeDialog = s_StartBakeDialogXOB;
169 if (!Workbench.ScriptDialog(bakeDialog.m_sTitle,
"Make sure you have supported version of Blender and newest EBT installed.", bakeDialog))
173 string pathToExecutable;
174 if (!EBTConfigPlugin.GetDefaultBlenderPath(pathToExecutable))
177 BlenderOperatorDescription operatorDescription =
new BlenderOperatorDescription(
"bake");
179 if (GetOperatorDescription(bakeDialog, resource, m_iNumberOfSamples, operatorDescription))
181 StartBlenderWithOperator(operatorDescription, m_bRunInBackground);
185 Print(
"Could not create a operatorDescription",
LogLevel.WARNING);
189 void VoidPrint(
void param)
195 override void OnResourceContextMenu(notnull array<ResourceName> resources)
197 if (resources.IsEmpty())
203 StartBake(resources[0]);
213 Workbench.ScriptDialog(
"MLOD Baker Settings",
"",
this);
219 [
Attribute(
"1024", UIWidgets.ComboBox,
"",
"", enums: ParamEnumTextureSize.FromEnum(),
category :
"Settings")]
224 int m_iSuperSampling;
226 [
Attribute(
"1024", UIWidgets.ComboBox,
"",
"", enums: ParamEnumTextureImportSize.FromEnum(),
category :
"Settings")]
227 int m_iTextureImportSize;
230 ref Color m_ClearColor =
new Color(0.5, 0.5, 0.5, 1);
233 float m_fCageExtrusion = 2.5;
236 float m_fRayDistance = 0.3;
238 [
Attribute(
"0", UIWidgets.ComboBox,
"",
"", enums: ParamEnumArray.FromEnum(FixRayMissType),
category :
"Settings")]
239 FixRayMissType m_eFixRayType;
241 [
Attribute(
"0", UIWidgets.ComboBox,
"",
"", enums: ParamEnumArray.FromEnum(FixRayMissExtents),
category :
"Settings")]
242 FixRayMissExtents m_eFixRayExtents;
245 bool m_bSkipInterior;
248 string m_sTitle =
"";
251 void StartBakeDialog(
string title)
271class StartBakeDialogXOB : StartBakeDialog
274 bool m_bSkipTransparent;
280 string m_sTexturePath;
283 string m_sTextureName;
286 bool m_bCreateNewTexture;
291class StartBakeDialogET : StartBakeDialog
294 string m_sNewTextureName;
301 void BakeInfoRequest()
311 if (worldEditor.IsPrefabEditMode() && api.GetEditorEntityCount() == 2)
312 entitySource = api.GetEditorEntity(1);
318 return ancestor.GetResourceName();
325[WorkbenchToolAttribute(name:
"Bake MLOD Texture", description:
"Bakes MLOD Texture", wbModules: {
"WorldEditor" }, shortcut:
"Ctrl+B", awesomeFontCode: 0xf7ec)]
326class BakeMlodTool : WorldEditorTool
330 WorldEditor worldEditor = Workbench.GetModule(WorldEditor);
332 if (!worldEditor.IsPrefabEditMode())
334 Print(
"MLOD Baking is possible only in Edit Mode",
LogLevel.WARNING);
338 BakeMLODPlugin bakePlugin = BakeMLODPlugin.GetInstance();
344 ResourceName openedPrefab = GetOpenedPrefab(worldEditor, m_API);
348 bakePlugin.StartBake(openedPrefab);
352 Print(
"Prefab not compatible for MLOD baking",
LogLevel.WARNING);
360 void BakeInfoResponse()
372class BakeInfo : NetApiHandler
377 return new BakeInfoRequest();
381 override JsonApiStruct
GetResponse(JsonApiStruct request)
383 BakeInfoRequest req = BakeInfoRequest.Cast(request);
384 BakeInfoResponse response =
new BakeInfoResponse();
386 BakeInfoDialog dialog =
new BakeInfoDialog();
388 Workbench.ScriptDialog(
"MLOD Baker", req.msg, dialog);
396 string prefabAbsPath;
397 string materialAbsPath;
398 string textureAbsPath;
399 string sourceMaterial;
401 void OverrideMeshObjectMaterialRequest()
403 RegV(
"prefabAbsPath");
404 RegV(
"materialAbsPath");
405 RegV(
"textureAbsPath");
406 RegV(
"sourceMaterial");
414 void OverrideMeshObjectMaterialResponse()
420static void BakeCreateEmat(
string absPath, array<string> properties)
425 ResourceManager resourceManager = Workbench.GetModule(ResourceManager);
428 for (
int i = 0; i < properties.Count(); i+=2)
430 if (
FilePath.IsAbsolutePath(properties[i+ 1]))
432 string importPath = properties[i+ 1];
438 MetaFile meta = resourceManager.GetMetaFile(importPath);
439 properties[i+ 1] = meta.GetResourceID();
440 cont.Set(properties[i], properties[i+ 1]);
444 cont.Set(properties[i], properties[i+ 1]);
450 resourceManager.RegisterResourceFile(absPath,
true);
451 resourceManager.WaitForFile(absPath, 3000);
455static bool ResourceExistsAndIsRegistered(
string absPath)
457 ResourceManager resourceManager = Workbench.GetModule(ResourceManager);
458 MetaFile metaFile = resourceManager.GetMetaFile(absPath);
462 return Workbench.GetAbsolutePath(metaFile.GetResourceID().GetPath(), dummyResult,
true);
467class OverrideMeshObjectMaterial : NetApiHandler
472 return new OverrideMeshObjectMaterialRequest();
478 BaseContainerList srcList = prefab.GetObjectArray(EBTContainerFields.components);
479 for (
int i = 0; i < srcList.Count(); i++)
481 prefab = srcList.Get(i);
482 if (prefab.GetClassName() == name)
491 override JsonApiStruct
GetResponse(JsonApiStruct request)
493 OverrideMeshObjectMaterialRequest req = OverrideMeshObjectMaterialRequest.Cast(request);
496 ResourceManager resourceManager = Workbench.GetModule(ResourceManager);
497 MetaFile prefabMeta = resourceManager.GetMetaFile(req.prefabAbsPath);
498 Resource resource = Resource.Load(prefabMeta.GetResourceID());
499 BaseContainer prefab = resource.GetResource().ToBaseContainer();
503 BaseContainerList components = prefab.GetObjectArray(EBTContainerFields.components);
505 BaseContainer prefabMeshObject = components.Get(meshParamID);
508 string sourceMaterialSlot = req.sourceMaterial;
510 if (ResourceExistsAndIsRegistered(req.materialAbsPath))
512 Print(
"MLOD BAKER: Material Already Exist. Skipping Creation",
LogLevel.NORMAL);
516 array<string> materialProps = {
"BCRMap", req.textureAbsPath,
"MetalnessScale",
"0,0",
"DisableInteriorProbes",
"1"};
517 BakeCreateEmat(req.materialAbsPath, materialProps);
520 MetaFile materialMeta = resourceManager.GetMetaFile(req.materialAbsPath);
521 ResourceName materialResourceName = materialMeta.GetResourceID();
523 BaseContainerList prefabMaterials = prefabMeshObject.GetObjectArray(
"Materials");
525 if (prefabMaterials.Count() != 0)
527 for (
int i = 0; i < prefabMaterials.Count(); i++)
529 BaseContainer material = prefabMaterials.Get(i);
530 ResourceName nameSrc;
532 material.Get(
"SourceMaterial", nameSrc);
534 if (nameSrc == sourceMaterialSlot)
536 ResourceName nameAssgn;
537 material.Get(
"AssignedMaterial", nameAssgn);
538 if (nameAssgn == materialResourceName)
540 Print(
"MLOD BAKER: Material Already Assigned. Skipping Assignment",
LogLevel.NORMAL);
544 WorldEditor worldEditorModule = Workbench.GetModule(WorldEditor);
545 WorldEditorAPI api = worldEditorModule.GetApi();
549 Workbench.OpenModule(WorldEditor);
550 api = worldEditorModule.GetApi();
553 ResourceName openedPrefab = GetOpenedPrefab(worldEditorModule, api);
554 if (openedPrefab != prefabMeta.GetResourceID())
555 worldEditorModule.SetOpenedResource(prefabMeta.GetResourceID());
557 bool manageEditAction = !api.IsDoingEditAction();
559 if (manageEditAction)
560 api.BeginEntityAction();
563 api.SaveEntityTemplate(prefab);
565 if (manageEditAction)
566 api.EndEntityAction();
573 WorldEditor worldEditorModule = Workbench.GetModule(WorldEditor);
574 WorldEditorAPI api = worldEditorModule.GetApi();
578 Workbench.OpenModule(WorldEditor);
579 api = worldEditorModule.GetApi();
582 ResourceName openedPrefab = GetOpenedPrefab(worldEditorModule, api);
583 if (openedPrefab != prefabMeta.GetResourceID())
584 worldEditorModule.SetOpenedResource(prefabMeta.GetResourceID());
586 bool manageEditAction = !api.IsDoingEditAction();
588 if (manageEditAction)
589 api.BeginEntityAction();
591 api.CreateObjectArrayVariableMember(prefab, {
ContainerIdPathEntry(
"MeshObject")},
"Materials",
"MaterialAssignClass", 0);
595 if (manageEditAction)
596 api.EndEntityAction();
598 api.SaveEntityTemplate(prefab);
602 OverrideMeshObjectMaterialResponse response =
new OverrideMeshObjectMaterialResponse();
override JsonApiStruct GetResponse(JsonApiStruct request)
void ParamEnum(string key, string value, string desc="")
ParamEnum Managed FromEnum(typename e)
void ContainerIdPathEntry(string propertyName, int index=-1)
ExportTerrainRequest Output
int GetPrefabParamIndex(BaseContainer prefab, string name)
SCR_AICombatMoveRequestBase GetRequest()
ResourceName resourceName
override void OnActivate()
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
class WorkbenchDialog_AbortRetryIgnore ButtonAttribute("OK", true)
base classes for filtering in server browser
Object holding reference to resource. In destructor release the resource.
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
SCR_FieldOfViewSettings Attribute
proto external string ToString()
Plain C++ pointer, no weak pointers, no memory management.