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.