Skip to content

Commit

Permalink
#5576: Moving pico-to-staticsurface conversion code to PicoModelLoader.
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Apr 4, 2021
1 parent 3885e8b commit 7537c3c
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 98 deletions.
86 changes: 3 additions & 83 deletions radiantcore/model/StaticModelSurface.cpp
Expand Up @@ -10,54 +10,16 @@

#include "string/replace.h"

namespace model {
namespace model
{

// Constructor. Copy the provided picoSurface_t structure into this object
StaticModelSurface::StaticModelSurface(picoSurface_t* surf,
const std::string& fExt)
StaticModelSurface::StaticModelSurface(picoSurface_t* surf)
: _defaultMaterial(""),
_dlRegular(0),
_dlProgramVcol(0),
_dlProgramNoVCol(0)
{
// Get the shader from the picomodel struct. If this is a LWO model, use
// the material name to select the shader, while for an ASE model the
// bitmap path should be used.
picoShader_t* shader = PicoGetSurfaceShader(surf);
std::string rawName = "";

if (shader != 0)
{
if (fExt == "lwo")
{
_defaultMaterial = PicoGetShaderName(shader);
}
else if (fExt == "ase")
{
rawName = PicoGetShaderName(shader);
std::string rawMapName = PicoGetShaderMapName(shader);
_defaultMaterial = cleanupShaderName(rawMapName);
}
else // if extension is not handled explicitly, use at least something
{
_defaultMaterial = PicoGetShaderName(shader);
}
}

// #4644: Doom3 / TDM don't use the *MATERIAL_NAME in ASE models, only *BITMAP is used
// Use the fallback (introduced in #2499) only when the game allows it
if (game::current::getValue<bool>("/modelFormat/ase/useMaterialNameIfNoBitmapFound"))
{
// If shader not found, fallback to alternative if available
// _defaultMaterial is empty if the ase material has no BITMAP
// materialIsValid is false if _defaultMaterial is not an existing shader
if ((_defaultMaterial.empty() || !GlobalMaterialManager().materialExists(_defaultMaterial)) &&
!rawName.empty())
{
_defaultMaterial = cleanupShaderName(rawName);
}
}

// Capturing the shader happens later on when we have a RenderSystem reference

// Get the number of vertices and indices, and reserve capacity in our
Expand Down Expand Up @@ -113,48 +75,6 @@ StaticModelSurface::StaticModelSurface(const StaticModelSurface& other) :
createDisplayLists();
}

std::string StaticModelSurface::cleanupShaderName(const std::string& inName)
{
const std::string baseFolder = "base"; //FIXME: should be from game.xml
std::size_t basePos;

std::string mapName = string::replace_all_copy(inName, "\\", "/");

// for paths given relative, start from the beginning
if (mapName.substr(0,6) == "models" || mapName.substr(0,8) == "textures")
{
basePos = 0;
}
else
{
// Take off the everything before "base/", and everything after
// the first period if it exists (i.e. strip off ".tga")
basePos = mapName.find(baseFolder);
if (basePos == std::string::npos)
{
// Unrecognised shader path, no base folder.
// Try the original incase it was already given relative.
basePos = 0;
}
else
{
// Increment for for the length of "base/", the / is the +1
basePos += (baseFolder.size() + 1);
}
}

std::size_t dotPos = mapName.find(".");

if (dotPos != std::string::npos)
{
return mapName.substr(basePos, dotPos - basePos);
}
else
{
return mapName.substr(basePos);
}
}

// Destructor. Release the GL display lists.
StaticModelSurface::~StaticModelSurface()
{
Expand Down
13 changes: 2 additions & 11 deletions radiantcore/model/StaticModelSurface.h
Expand Up @@ -74,20 +74,11 @@ class StaticModelSurface :
std::string cleanupShaderName(const std::string& mapName);

public:
/**
* Constructor. Accepts a picoSurface_t struct and the file extension to determine
* how to assign materials.
*/
StaticModelSurface(picoSurface_t* surf, const std::string& fExt);
StaticModelSurface(picoSurface_t* surf);

/**
* Copy-constructor.
*/
// Copy-constructor.
StaticModelSurface(const StaticModelSurface& other);

/**
* Destructor.
*/
~StaticModelSurface();

/**
Expand Down
23 changes: 23 additions & 0 deletions radiantcore/model/import/AseModel.cpp
@@ -1,3 +1,5 @@
#include "AseModel.h"

/* -----------------------------------------------------------------------------
PicoModel Library
Expand Down Expand Up @@ -543,6 +545,27 @@ static void shadername_convert(char* shaderName)
}
}

namespace model
{

#if 0
StaticModelSurface& AseModel::addSurface()
{
return *_surfaces.emplace_back(std::make_shared<StaticModelSurface>());
}
#endif

const std::vector<StaticModelSurfacePtr>& AseModel::getSurfaces() const
{
return _surfaces;
}

std::shared_ptr<AseModel> AseModel::CreateFromStream(std::istream& stream)
{
return std::make_shared<AseModel>();
}

}

/* _ase_load:
* loads a 3dsmax ase model file.
Expand Down
22 changes: 22 additions & 0 deletions radiantcore/model/import/AseModel.h
@@ -0,0 +1,22 @@
#pragma once

#include <istream>
#include "../StaticModelSurface.h"

namespace model
{

class AseModel
{
private:
std::vector<StaticModelSurfacePtr> _surfaces;

public:
StaticModelSurface& addSurface();

const std::vector<StaticModelSurfacePtr>& getSurfaces() const;

static std::shared_ptr<AseModel> CreateFromStream(std::istream& stream);
};

}
18 changes: 15 additions & 3 deletions radiantcore/model/import/AseModelLoader.cpp
@@ -1,5 +1,8 @@
#include "AseModelLoader.h"

#include <istream>
#include "AseModel.h"

#include "../picomodel/lib/picomodel.h"
#include "os/path.h"
#include "string/case_conv.h"
Expand Down Expand Up @@ -28,8 +31,8 @@ IModelPtr AseModelLoader::loadModelFromPath(const std::string& path)
{
// Open an ArchiveFile to load
auto file = path_is_absolute(path.c_str()) ?
GlobalFileSystem().openFileInAbsolutePath(path) :
GlobalFileSystem().openFile(path);
GlobalFileSystem().openTextFileInAbsolutePath(path) :
GlobalFileSystem().openTextFile(path);

if (!file)
{
Expand Down Expand Up @@ -64,7 +67,16 @@ IModelPtr AseModelLoader::loadModelFromPath(const std::string& path)

return modelObj;
#else
return IModelPtr();
std::istream stream(&(file->getInputStream()));
auto model = AseModel::CreateFromStream(stream);

auto modelObj = std::make_shared<StaticModel>(model->getSurfaces());

// Set the filename
modelObj->setFilename(os::getFilename(file->getName()));
modelObj->setModelPath(path);

return modelObj;
#endif
}

Expand Down
94 changes: 93 additions & 1 deletion radiantcore/model/picomodel/PicoModelLoader.cpp
Expand Up @@ -3,8 +3,10 @@
#include "ifilesystem.h"
#include "iarchive.h"
#include "imodelcache.h"
#include "ishaders.h"

#include "lib/picomodel.h"
#include "gamelib.h"

#include "os/path.h"

Expand Down Expand Up @@ -99,6 +101,92 @@ std::vector<StaticModelSurfacePtr> PicoModelLoader::CreateSurfaces(picoModel_t*
return surfaces;
}

std::string PicoModelLoader::CleanupShaderName(const std::string& inName)
{
const std::string baseFolder = "base"; //FIXME: should be from game.xml
std::size_t basePos;

std::string mapName = string::replace_all_copy(inName, "\\", "/");

// for paths given relative, start from the beginning
if (mapName.substr(0, 6) == "models" || mapName.substr(0, 8) == "textures")
{
basePos = 0;
}
else
{
// Take off the everything before "base/", and everything after
// the first period if it exists (i.e. strip off ".tga")
basePos = mapName.find(baseFolder);
if (basePos == std::string::npos)
{
// Unrecognised shader path, no base folder.
// Try the original incase it was already given relative.
basePos = 0;
}
else
{
// Increment for for the length of "base/", the / is the +1
basePos += (baseFolder.size() + 1);
}
}

std::size_t dotPos = mapName.find(".");

if (dotPos != std::string::npos)
{
return mapName.substr(basePos, dotPos - basePos);
}
else
{
return mapName.substr(basePos);
}
}

std::string PicoModelLoader::DetermineDefaultMaterial(picoSurface_t* picoSurface, const std::string& extension)
{
// Get the shader from the picomodel struct. If this is a LWO model, use
// the material name to select the shader, while for an ASE model the
// bitmap path should be used.
picoShader_t* shader = PicoGetSurfaceShader(picoSurface);
std::string rawName = "";
std::string defaultMaterial;

if (shader != 0)
{
if (extension == "lwo")
{
defaultMaterial = PicoGetShaderName(shader);
}
else if (extension == "ase")
{
rawName = PicoGetShaderName(shader);
std::string rawMapName = PicoGetShaderMapName(shader);
defaultMaterial = CleanupShaderName(rawMapName);
}
else // if extension is not handled explicitly, use at least something
{
defaultMaterial = PicoGetShaderName(shader);
}
}

// #4644: Doom3 / TDM don't use the *MATERIAL_NAME in ASE models, only *BITMAP is used
// Use the fallback (introduced in #2499) only when the game allows it
if (game::current::getValue<bool>("/modelFormat/ase/useMaterialNameIfNoBitmapFound"))
{
// If shader not found, fallback to alternative if available
// _defaultMaterial is empty if the ase material has no BITMAP
// materialIsValid is false if _defaultMaterial is not an existing shader
if ((defaultMaterial.empty() || !GlobalMaterialManager().materialExists(defaultMaterial)) &&
!rawName.empty())
{
defaultMaterial = CleanupShaderName(rawName);
}
}

return defaultMaterial;
}

StaticModelSurfacePtr PicoModelLoader::CreateSurface(picoSurface_t* picoSurface, const std::string& extension)
{
if (picoSurface == 0 || PicoGetSurfaceType(picoSurface) != PICO_TRIANGLES)
Expand All @@ -110,7 +198,11 @@ StaticModelSurfacePtr PicoModelLoader::CreateSurface(picoSurface_t* picoSurface,
PicoFixSurfaceNormals(picoSurface);

// Create the StaticModelSurface object and add it to the vector
return std::make_shared<StaticModelSurface>(picoSurface, extension);
auto staticSurface = std::make_shared<StaticModelSurface>(picoSurface);

staticSurface->setDefaultMaterial(DetermineDefaultMaterial(picoSurface, extension));

return staticSurface;
}

} // namespace model
4 changes: 4 additions & 0 deletions radiantcore/model/picomodel/PicoModelLoader.h
Expand Up @@ -25,7 +25,11 @@ class PicoModelLoader :
public:
static std::vector<StaticModelSurfacePtr> CreateSurfaces(picoModel_t* picoModel, const std::string& extension);

static std::string DetermineDefaultMaterial(picoSurface_t* picoSurface, const std::string& extension);

private:
static std::string CleanupShaderName(const std::string& inName);

static StaticModelSurfacePtr CreateSurface(picoSurface_t* picoSurface, const std::string& extension);
};

Expand Down
1 change: 1 addition & 0 deletions tools/msvc/DarkRadiantCore.vcxproj
Expand Up @@ -858,6 +858,7 @@
<ClInclude Include="..\..\radiantcore\model\export\PatchSurface.h" />
<ClInclude Include="..\..\radiantcore\model\export\ScaledModelExporter.h" />
<ClInclude Include="..\..\radiantcore\model\export\WavefrontExporter.h" />
<ClInclude Include="..\..\radiantcore\model\import\AseModel.h" />
<ClInclude Include="..\..\radiantcore\model\import\AseModelLoader.h" />
<ClInclude Include="..\..\radiantcore\model\import\ModelImporterBase.h" />
<ClInclude Include="..\..\radiantcore\model\md5\MD5Anim.h" />
Expand Down
3 changes: 3 additions & 0 deletions tools/msvc/DarkRadiantCore.vcxproj.filters
Expand Up @@ -2112,5 +2112,8 @@
<ClInclude Include="..\..\radiantcore\model\StaticModelSurface.h">
<Filter>src\model</Filter>
</ClInclude>
<ClInclude Include="..\..\radiantcore\model\import\AseModel.h">
<Filter>src\model\import</Filter>
</ClInclude>
</ItemGroup>
</Project>

0 comments on commit 7537c3c

Please sign in to comment.