Tutorial_Generation_cellbox.cpp

Tutorial_Generation_cellbox.cpp
/*
* Copyright 2015 Autodesk, Inc. All rights reserved.
* Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
* or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
*/
#include "common/basesystemenv.h"
#include "common/GeneratorEnvInit.h"
//RUN_THIS_FILE
namespace
{
// This tutorial illustrates the use of InputCellbox as a way to limit the generation
// of overlap data when the geometry of sectors is consistent (for instance, it is aligned on a grid of cellsize).
// It enables the generation of lighter set of pathdata without compromising the stitching capabilities at runtime.
class Tutorial_Generation_CellBox : public BaseSystemEnv
{
public:
// This is used to set up the Alloc instance for the generation,
// and the log for the Tutorial.
typedef GeneratorEnvInit InitClass;
public:
bool GenerateMultisector(bool useCellBox)
{
// Create the producer using the class coded above.
Kaim::Ptr<Kaim::OBJProducer> producer = *KY_NEW Kaim::OBJProducer;
// Set up a generator using the OBJ Producer and the default Glue.
Kaim::Generator generator(producer, &defaultGlue);
// Set the Directory where the navdata and clientInput files
// will be saved.
generator.SetOutputDirectory(RootDir().c_str(), RelativeOutputDir().c_str());
// Add the four sectors of the village WITH cellboxes to limit the generation of overlap data.
Kaim::GeneratorInputOutput generatorInputOutput;
std::string sectorName = (useCellBox ? "Village_A" : "Village_A_noCellBox");
Kaim::Ptr<Kaim::GeneratorSector> sectorA = *KY_NEW Kaim::GeneratorSector(KyGlue::DefaultGuidGeneratorInterface::GenerateGuid(), sectorName.c_str());
sectorA->m_inputFileNames.PushBack(GetAbsoluteInputFileName("common/Village_250x200_multisector/Village_250x200_Sector_A.obj").c_str());
sectorName = (useCellBox ? "Village_B" : "Village_B_noCellBox");
Kaim::Ptr<Kaim::GeneratorSector> sectorB = *KY_NEW Kaim::GeneratorSector(KyGlue::DefaultGuidGeneratorInterface::GenerateGuid(), sectorName.c_str());
sectorB->m_inputFileNames.PushBack(GetAbsoluteInputFileName("common/Village_250x200_multisector/Village_250x200_Sector_B.obj").c_str());
sectorName = (useCellBox ? "Village_C" : "Village_C_noCellBox");
Kaim::Ptr<Kaim::GeneratorSector> sectorC = *KY_NEW Kaim::GeneratorSector(KyGlue::DefaultGuidGeneratorInterface::GenerateGuid(), sectorName.c_str());
sectorC->m_inputFileNames.PushBack(GetAbsoluteInputFileName("common/Village_250x200_multisector/Village_250x200_Sector_C.obj").c_str());
sectorName = (useCellBox ? "Village_D" : "Village_D_noCellBox");
Kaim::Ptr<Kaim::GeneratorSector> sectorD = *KY_NEW Kaim::GeneratorSector(KyGlue::DefaultGuidGeneratorInterface::GenerateGuid(), sectorName.c_str());
sectorD->m_inputFileNames.PushBack(GetAbsoluteInputFileName("common/Village_250x200_multisector/Village_250x200_Sector_D.obj").c_str());
// In this section, cell boxes are set to limit the expansion of each sector to within specific bounds.
// NOTE: during generation, the geometry from all sectors overlapping a certain
// cell is aggregated, but the resulting NavCell will only be present in the cellbox of the sector(s)
// containing this particular cell. This may result in small inconsistencies between the geometry of a particular
// sector and its NavMeshElements until the geometry from the neighboring cells have been streamed-in.
// In this particular case, we assign each sector a cellBox following the layout pattern below.
// In this case, the cell boxes do not overlap but form a consistent pattern; it should
// stitch together properly, and no overlap will be generated.
//
// cell -2,12 cell -1,12
// | |
// ________________________________
// | | | <- cell 12,12
// | | |
// | Village | Village |
// | C | B |
// | | |
// |_______________+_+______________| <- cell 12,-1
// | | | <- cell 12,0
// | | |
// | Village D | Village |
// | | A |
// | | |
// |_________________+______________| <- cell 12,-12
// | |
// cell-1,-12 cell 0,-12
//
if (useCellBox)
{
sectorA->m_navDataCellBox.Set(Kaim::Vec2i(0, -12), Kaim::Vec2i(12, 0));
sectorB->m_navDataCellBox.Set(Kaim::Vec2i(-1, 1), Kaim::Vec2i(12, 12));
sectorC->m_navDataCellBox.Set(Kaim::Vec2i(-15, 1), Kaim::Vec2i(-2, 12));
sectorD->m_navDataCellBox.Set(Kaim::Vec2i(-15, -12), Kaim::Vec2i(-1, 0));
}
generatorInputOutput.AddSector(sectorA);
generatorInputOutput.AddSector(sectorB);
generatorInputOutput.AddSector(sectorC);
generatorInputOutput.AddSector(sectorD);
// This command does not log the report, but does log the overlap data size (see below).
generatorInputOutput.m_runOptions.m_doLogReport = false;
// This stage is complete, the generator can run using the configuration established above.
if (generator.Generate(generatorInputOutput) == KY_ERROR)
return false;
// Report the size of the overlap data.
KyUInt32 sizeOfOverlapData = 0;
for (KyUInt32 i = 0; i < sectorStats.GetCount(); ++i)
sizeOfOverlapData += sectorStats[i].m_overlapDataSizeInBytes;
if (!useCellBox)
KY_LOG_MESSAGE(("Generation with no cellBox: %i bytes of overlap data", sizeOfOverlapData));
else
KY_LOG_MESSAGE(("Generation with cellBox: %i bytes of overlap data", sizeOfOverlapData));
return true;
}
};
#define TEST_ENV_CLASS Tutorial_Generation_CellBox
TEST_ENV {}
TUTORIAL { CHECK(env.GenerateMultisector(false)) }
TUTORIAL { CHECK(env.GenerateMultisector(true)) }
}