Using dynamic optimization
Posted: Tue Jan 25, 2022 4:35 pm
This article is to be read after : Details on CSceneOptimizer (static optimization)
You may though to use dynamic optimization if you have to modify the optimization ratio multiple time. This can be the case for adjusting the ratio depending on a camera position : the closer the camera to the objet the higher the optimization ratio.
You also have to use dynamic resolution if you plan to use MagicCruncher.
First you must have a scene and prepare it for optimization:
Then you must turn on SCENEOPTIMIZER_TRACK_CHANGES. This is require to be able to get multi resolution objet.
The following code prepare the optimizer and do the optimization computation to the maximum ratio.
Doing that optimization track optimization computation for every meshes from its original state to its maximum optimization.
No we have a an optimized scene from which we can get a dynamic scene.
Now we have a dynamic scene and we can play with the ratio.
This can be done globally for the whole scene using CSceneOptimizer::SetMultiresolutionRatio
Note that you can also get access to multiresolution meshes individually and set a different ratio for each one:
You can also use MagicCruncher because using the appropriate ratio might be difficult to determine.
MagicCruncher requires to have a dynamic scene... but all this will be explained in another post.
You may though to use dynamic optimization if you have to modify the optimization ratio multiple time. This can be the case for adjusting the ratio depending on a camera position : the closer the camera to the objet the higher the optimization ratio.
You also have to use dynamic resolution if you plan to use MagicCruncher.
First you must have a scene and prepare it for optimization:
Code: Select all
CSceneImportOptions options;
options.flags = SCENE_IMPORT_GENERATE_UV;
CXString filename = "YOUR_FILENAME_HERE";
C3DIo file(filename, FILE_PARSER_LOADING);
C3DScene *scene = file.Read(&options);
if (!scene)
{
_tprintf(FormatString(_T("There was an error when reading the file %s\r\n"), (LPCTSTR)filename));
return 1;
}
// Very important !
// Convert scene and use C3DExtObject king of object.
// This type is required for optimizing. If ommit, no optimization is performed
C3DPolygonCruncherObjectCreator cruncherCreator(DEFAULT_OPTIMIZATION_OBJECT);
scene->ConvertToType(NULL, &cruncherCreator);
CSceneOptimizer *optimizer = xNew(CSceneOptimizer);
optimizer->SetFlag(SCENEOPTIMIZER_PROGRESSIVE_RATIO, true); // No matter is trying on the capsule, but it gives better results you have several objects
optimizer->SetScene(*scene, true);
The following code prepare the optimizer and do the optimization computation to the maximum ratio.
Doing that optimization track optimization computation for every meshes from its original state to its maximum optimization.
Code: Select all
optimizer->SetFlag(SCENEOPTIMIZER_TRACK_CHANGES, true); // Turn on dynamic optimization capabilities
#define DEFAULT_OPTIMIZATION_MODE OPTIMIZE_PROTECT_BORDER|OPTIMIZE_VERIFY_PAIRS_MASK|OPTIMIZE_KEEP_MATERIAL_FRONTIER|OPTIMIZE_PROTECT_MATERIAL_FRONTIER|OPTIMIZE_KEEP_UV|OPTIMIZE_PROTECT_UV
// Define some optimization settings
optimizer->SetOptimizeMode(DEFAULT_OPTIMIZATION_MODE, true);
bool cancel;
optimizer->Optimize(0.0f, cancel); // Optimize the whole scene at its maximum ratio.Note: if you use another ratio R (< 1.0), then the dynamic object ratio range will be possible from 1.0 to R only (which might be enough!)
Code: Select all
// Get a dynamic scene which is made of dynamic objects. Each one have the class CMultiresolutionObject.
C3DScene *optimizescene = optimizer->GetScene(OPTIMIZED_MULTIRESOLUTION_SCENE); // Compute the multiresolution scene
if (!optimizescene)
{
xDelete(optimizer);
return 1;
}
// at this point the loaded scene is not useful anymore. We have a dynamic copy of it.
// We can delete it to limit memory needs
optimizer->DeleteScene();
This can be done globally for the whole scene using CSceneOptimizer::SetMultiresolutionRatio
Code: Select all
char key = 0;
while (key != ' ')
{
key = getch();
bool predictive = false, magic = false;
if (key == '+')
ratio += 0.1f;
else if (key == '-')
ratio -= 0.1f;
optimizer->SetMultiresolutionRatio(ratio, 0, OPTIMIZE_TO_POINT|OPTIMIZE_TO_RATIO);
}
Code: Select all
// Select all instance of the selected nodes
C3DSceneNode *node;
C3DBaseObject *baseobject;
CMultiresolutionObject *multires = NULL;
C3DNodePos pos = scene->GetFirstNode(OBJECT_GEOM);
while (pos)
{
node = scene->GetNextNode(baseobject, pos);
if (!baseobject->IsKindOf(XRUNTIME_CLASS(CMultiresolutionObject)))
continue;
multires= (CMultiresolutionObject *)baseobject;
multires->SetObjectRatio(GetRatioFromDistToCamera(), , OPTIMIZE_TO_POINT|OPTIMIZE_TO_RATIO); // Optimize the object using a condition
}
MagicCruncher requires to have a dynamic scene... but all this will be explained in another post.