Groundwork

Adds the same sort of model for registering loaders and exporters as is set out on gbitmap
Added a bit more safety around the assimp matrix fix to convert incoming models to torques coordinate system.
This commit is contained in:
marauder2k7 2026-05-01 16:43:58 +01:00
parent 8407fa360c
commit ee04b0cf15
9 changed files with 238 additions and 358 deletions

View file

@ -50,7 +50,24 @@
#include "core/util/zip/zipVolume.h"
#include "gfx/bitmap/gBitmap.h"
extern bool gTryUseDSQs;
static bool sReadCollada(const Torque::Path& path, TSShape*& shape);
static struct _privateRegisterCollada
{
_privateRegisterCollada()
{
TSShape::ShapeRegistration reg;
reg.extensions.push_back({ "Collada", "dae" });
reg.export_extensions.push_back({ "Collada", "dae" });
reg.extensions.push_back({ "Google Earth", "kmz" });
reg.readFunc = sReadCollada;
reg.writeFunc = NULL;
TSShape::sRegisterFormat(reg);
}
} sStaticRegisterCollada;
MODULE_BEGIN( ColladaShapeLoader )
MODULE_INIT_AFTER( ShapeLoader )
MODULE_INIT
@ -549,39 +566,6 @@ bool ColladaShapeLoader::canLoadCachedDTS(const Torque::Path& path)
return false;
}
bool ColladaShapeLoader::canLoadCachedDSQ(const Torque::Path& path)
{
// Generate the cached filename
Torque::Path cachedPath(path);
cachedPath.setExtension("dsq");
// Check if a cached DSQ newer than this file is available
FileTime cachedModifyTime;
if (Platform::getFileTimes(cachedPath.getFullPath(), NULL, &cachedModifyTime))
{
bool forceLoadDAE = Con::getBoolVariable("$collada::forceLoadDAE", false);
FileTime daeModifyTime;
if (!Platform::getFileTimes(path.getFullPath(), NULL, &daeModifyTime) ||
(!forceLoadDAE && (Platform::compareFileTimes(cachedModifyTime, daeModifyTime) >= 0)))
{
// DAE not found, or cached DTS is newer
return true;
}
}
//assume the dts is good since it was zipped on purpose
Torque::FS::FileSystemRef ref = Torque::FS::GetFileSystem(cachedPath);
if (ref && !String::compare("Zip", ref->getTypeStr().c_str()))
{
bool forceLoadDAE = Con::getBoolVariable("$collada::forceLoadDAE", false);
if (!forceLoadDAE && Torque::FS::IsFile(cachedPath))
return true;
}
return false;
}
bool ColladaShapeLoader::checkAndMountSketchup(const Torque::Path& path, String& mountPoint, Torque::Path& daePath)
{
bool isSketchup = path.getExtension().equal("kmz", String::NoCase);
@ -683,61 +667,8 @@ domCOLLADA* ColladaShapeLoader::readColladaFile(const String& path)
//-----------------------------------------------------------------------------
/// This function is invoked by the resource manager based on file extension.
TSShape* loadColladaShape(const Torque::Path &path)
static bool sReadCollada(const Torque::Path& path, TSShape*& res_shape)
{
#ifndef DAE2DTS_TOOL
// Generate the cached filename
Torque::Path cachedPath(path);
bool canLoadCached = false;
bool canLoadDSQ = false;
// Check if an up-to-date cached DTS version of this file exists, and
// if so, use that instead.
if (ColladaShapeLoader::canLoadCachedDTS(path))
{
cachedPath.setExtension("cached.dts");
canLoadCached = true;
}
else if (gTryUseDSQs && ColladaShapeLoader::canLoadCachedDSQ(path))
{
cachedPath.setExtension("dsq");
canLoadDSQ = true;
}
if (canLoadCached || canLoadDSQ)
{
FileStream cachedStream;
cachedStream.open(cachedPath.getFullPath(), Torque::FS::File::Read);
if (cachedStream.getStatus() == Stream::Ok)
{
TSShape *shape = new TSShape;
bool readSuccess = false;
if (canLoadCached)
{
readSuccess = shape->read(&cachedStream);
}
else
{
readSuccess = shape->importSequences(&cachedStream, cachedPath);
}
cachedStream.close();
if (readSuccess)
{
#ifdef TORQUE_DEBUG
Con::printf("Loaded cached Collada shape from %s", cachedPath.getFullPath().c_str());
#endif
return shape;
}
else
{
#ifdef TORQUE_DEBUG
Con::errorf("loadColladaShape: Load sequence file '%s' failed", cachedPath.getFullPath().c_str());
#endif
delete shape;
}
}
}
#endif // DAE2DTS_TOOL
if (!Torque::FS::IsFile(path))
{
// DAE file does not exist, bail.
@ -777,58 +708,31 @@ TSShape* loadColladaShape(const Torque::Path &path)
tss = loader.generateShape(daePath);
if (tss)
{
#ifndef DAE2DTS_TOOL
TSShapeLoader::updateProgress(TSShapeLoader::Load_Complete, "Import complete");
Con::printf("[COLLADA] Shape created successfully.");
bool realMesh = false;
for (U32 i = 0; i < tss->meshes.size(); ++i)
Torque::Path cachedPath(path);
// Cache the model to a DTS file for faster loading next time.
cachedPath.setExtension("cached.dts");
// Cache the model to a DTS file for faster loading next time.
FileStream dtsStream;
if (dtsStream.open(cachedPath.getFullPath(), Torque::FS::File::Write))
{
if (tss->meshes[i] && tss->meshes[i]->getMeshType() != TSMesh::NullMeshType)
realMesh = true;
Con::printf("Writing cached shape to %s", cachedPath.getFullPath().c_str());
tss->write(&dtsStream);
}
if (!realMesh && gTryUseDSQs)
{
Torque::Path dsqPath(cachedPath);
dsqPath.setExtension("dsq");
FileStream animOutStream;
dsqPath.setFileName(cachedPath.getFileName());
if (animOutStream.open(dsqPath.getFullPath(), Torque::FS::File::Write))
{
Con::printf("Writing DSQ Animation File for '%s'", dsqPath.getFileName().c_str());
tss->exportSequences(&animOutStream);
animOutStream.close();
}
}
else
{
// Cache the Collada model to a DTS file for faster loading next time.
cachedPath.setExtension("cached.dts");
FileStream dtsStream;
if (dtsStream.open(cachedPath.getFullPath(), Torque::FS::File::Write))
{
Torque::FS::FileSystemRef ref = Torque::FS::GetFileSystem(daePath);
if (ref && !String::compare("Zip", ref->getTypeStr().c_str()))
Con::errorf("No cached dts file found in archive for %s. Forcing cache to disk.", daePath.getFullFileName().c_str());
Con::printf("Writing cached COLLADA shape to %s", cachedPath.getFullPath().c_str());
tss->write(&dtsStream);
}
}
#endif // DAE2DTS_TOOL
// Add collada materials to materials.tscript
updateMaterialsScript(path, isSketchup);
}
}
// Close progress dialog
TSShapeLoader::updateProgress(TSShapeLoader::Load_Complete, "Import complete");
if (isSketchup)
{
// Unmount the zip if we mounted it
Torque::FS::Unmount(mountPoint);
}
return tss;
res_shape = tss;
return true;
}