mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-09-09 07:27:05 +00:00
feat: QOS (007: Quantum of Solace) support (#894)
* feat: QOS (007: Quantum of Solace) support * feat: add qos localize loader * feat: add qos stringtable loader * chore: comment about official zones * fix: add qos gfximage runtime fields * chore: remove useless dev time comments * fix: remove all `static_asserts`s from asset headers causing build fail on x64 * chore: change union ordering of qos `entryInternalData` * chore: move qos asset type enum to qos.h * fix: qos and t4 xsurface index buffer * chore: implement qos MaterialInfo struct * chore: adjust some gfxworld struct members * chore: implement qos PhysPreset and PhysConstraints * chore: fix and adjust slight inconsistencies with qos zone code * chore: reorder qos ZoneCode.lua entries in order of asset type enum * chore: remove asset types that are not actual asset types in zones * chore: check common asset arrays with static_assert * chore: rename qos assets * chore: reorder qos in templates to be in alphabetical order * chore: use function for CopyMipLevel in Dx9TextureLoader * chore: use templates for qos MapEntsDumper * chore: add missing braces in XModelToCommonConverter * chore: add generic way to peek at zone data * Qos does not use a classic ZoneHeader so code needs to be more generic * fix: do not use raw_byte and raw_uint typedefs for qos * fix: not being able to write clipmapmp * chore: additional research on qos vertex property and stuff --------- Co-authored-by: Jan Laupetin <[email protected]>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#options GAME (IW3, IW4, IW5, T4, T5, T6)
|
||||
#options GAME (IW3, IW4, IW5, QOS, T4, T5, T6)
|
||||
|
||||
#filename "Game/" + GAME + "/Font/FontDumper" + GAME + ".cpp"
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#define GAME_LOWER "iw4"
|
||||
#elif GAME == "IW5"
|
||||
#define GAME_LOWER "iw5"
|
||||
#elif GAME == "QOS"
|
||||
#define FEATURE_QOS
|
||||
#define GAME_LOWER "qos"
|
||||
#elif GAME == "T4"
|
||||
#define GAME_LOWER "t4"
|
||||
#elif GAME == "T5"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#options GAME (IW3, IW4, IW5, T4, T5, T6)
|
||||
#options GAME (IW3, IW4, IW5, QOS, T4, T5, T6)
|
||||
|
||||
#filename "Game/" + GAME + "/Font/FontDumper" + GAME + ".h"
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "LocalizeDumperQOS.h"
|
||||
|
||||
#include "Dumping/Localize/StringFileDumper.h"
|
||||
#include "Localize/LocalizeCommon.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <format>
|
||||
|
||||
using namespace QOS;
|
||||
|
||||
namespace localize
|
||||
{
|
||||
void DumperQOS::Dump(AssetDumpingContext& context)
|
||||
{
|
||||
auto localizeAssets = context.m_zone.m_pools.PoolAssets<AssetLocalize>();
|
||||
if (localizeAssets.empty())
|
||||
return;
|
||||
|
||||
const auto language = LocalizeCommon::GetNameOfLanguage(context.m_zone.m_language);
|
||||
const auto assetFile = context.OpenAssetFile(std::format("{}/localizedstrings/{}.str", language, context.m_zone.m_name));
|
||||
|
||||
if (assetFile)
|
||||
{
|
||||
StringFileDumper stringFileDumper(context.m_zone, *assetFile);
|
||||
|
||||
stringFileDumper.SetLanguageName(language);
|
||||
stringFileDumper.SetConfigFile(R"(C:/trees/cod3/cod3/bin/StringEd.cfg)");
|
||||
stringFileDumper.SetNotes("");
|
||||
|
||||
for (const auto* localizeEntry : localizeAssets)
|
||||
stringFileDumper.WriteLocalizeEntry(localizeEntry->m_name, localizeEntry->Asset()->value);
|
||||
|
||||
stringFileDumper.Finalize();
|
||||
}
|
||||
else
|
||||
{
|
||||
con::error("Could not create string file for dumping localized strings of zone '{}'", context.m_zone.m_name);
|
||||
}
|
||||
|
||||
context.IncrementProgress();
|
||||
}
|
||||
} // namespace localize
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Dumping/AbstractAssetDumper.h"
|
||||
#include "Game/QOS/QOS.h"
|
||||
|
||||
namespace localize
|
||||
{
|
||||
class DumperQOS final : public AbstractSingleProgressAssetDumper<QOS::AssetLocalize>
|
||||
{
|
||||
public:
|
||||
void Dump(AssetDumpingContext& context) override;
|
||||
};
|
||||
} // namespace localize
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "ObjWriterQOS.h"
|
||||
|
||||
#include "Game/QOS/Font/FontDumperQOS.h"
|
||||
#include "Game/QOS/Image/ImageDumperQOS.h"
|
||||
#include "Game/QOS/Maps/MapEntsDumperQOS.h"
|
||||
#include "Game/QOS/XModel/XModelDumperQOS.h"
|
||||
#include "Localize/LocalizeDumperQOS.h"
|
||||
#include "RawFile/RawFileDumperQOS.h"
|
||||
#include "StringTable/StringTableDumperQOS.h"
|
||||
|
||||
using namespace QOS;
|
||||
|
||||
void ObjWriter::RegisterAssetDumpers(AssetDumpingContext& context)
|
||||
{
|
||||
RegisterAssetDumper(std::make_unique<font::JsonDumperQOS>());
|
||||
RegisterAssetDumper(std::make_unique<image::DumperQOS>());
|
||||
RegisterAssetDumper(std::make_unique<localize::DumperQOS>());
|
||||
RegisterAssetDumper(std::make_unique<map_ents::DumperQOS>());
|
||||
RegisterAssetDumper(std::make_unique<raw_file::DumperQOS>());
|
||||
RegisterAssetDumper(std::make_unique<string_table::DumperQOS>());
|
||||
RegisterAssetDumper(std::make_unique<xmodel::DumperQOS>());
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "ObjWriter.h"
|
||||
|
||||
namespace QOS
|
||||
{
|
||||
class ObjWriter final : public IObjWriter
|
||||
{
|
||||
protected:
|
||||
void RegisterAssetDumpers(AssetDumpingContext& context) override;
|
||||
};
|
||||
} // namespace QOS
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "RawFileDumperQOS.h"
|
||||
|
||||
using namespace QOS;
|
||||
|
||||
namespace raw_file
|
||||
{
|
||||
void DumperQOS::DumpAsset(AssetDumpingContext& context, const XAssetInfo<RawFile>& asset)
|
||||
{
|
||||
const auto* rawFile = asset.Asset();
|
||||
const auto assetFile = context.OpenAssetFile(asset.m_name);
|
||||
|
||||
if (!assetFile)
|
||||
return;
|
||||
|
||||
auto& stream = *assetFile;
|
||||
stream.write(rawFile->buffer, rawFile->len);
|
||||
}
|
||||
} // namespace raw_file
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Dumping/AbstractAssetDumper.h"
|
||||
#include "Game/QOS/QOS.h"
|
||||
|
||||
namespace raw_file
|
||||
{
|
||||
class DumperQOS final : public AbstractAssetDumper<QOS::AssetRawFile>
|
||||
{
|
||||
protected:
|
||||
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<QOS::RawFile>& asset) override;
|
||||
};
|
||||
} // namespace raw_file
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "StringTableDumperQOS.h"
|
||||
|
||||
#include "Csv/CsvStream.h"
|
||||
|
||||
using namespace QOS;
|
||||
|
||||
namespace string_table
|
||||
{
|
||||
void DumperQOS::DumpAsset(AssetDumpingContext& context, const XAssetInfo<StringTable>& asset)
|
||||
{
|
||||
const auto* stringTable = asset.Asset();
|
||||
const auto assetFile = context.OpenAssetFile(asset.m_name);
|
||||
|
||||
if (!assetFile)
|
||||
return;
|
||||
|
||||
CsvOutputStream csv(*assetFile);
|
||||
|
||||
for (auto row = 0; row < stringTable->rowCount; row++)
|
||||
{
|
||||
for (auto column = 0; column < stringTable->columnCount; column++)
|
||||
{
|
||||
csv.WriteColumn(stringTable->values[column + row * stringTable->columnCount]);
|
||||
}
|
||||
|
||||
csv.NextRow();
|
||||
}
|
||||
}
|
||||
} // namespace string_table
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Dumping/AbstractAssetDumper.h"
|
||||
#include "Game/QOS/QOS.h"
|
||||
|
||||
namespace string_table
|
||||
{
|
||||
class DumperQOS final : public AbstractAssetDumper<QOS::AssetStringTable>
|
||||
{
|
||||
protected:
|
||||
void DumpAsset(AssetDumpingContext& context, const XAssetInfo<QOS::StringTable>& asset) override;
|
||||
};
|
||||
} // namespace string_table
|
||||
@@ -1,4 +1,4 @@
|
||||
#options GAME (IW3, IW4, IW5, T4, T5, T6)
|
||||
#options GAME (IW3, IW4, IW5, QOS, T4, T5, T6)
|
||||
|
||||
#filename "Game/" + GAME + "/Image/ImageDumper" + GAME + ".cpp"
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#define FEATURE_IW5
|
||||
#define DX9
|
||||
#define IWI8
|
||||
#elif GAME == "QOS"
|
||||
#define FEATURE_QOS
|
||||
#define DX9
|
||||
#define IWI6
|
||||
#elif GAME == "T4"
|
||||
#define FEATURE_T4
|
||||
#define DX9
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#options GAME(IW3, IW4, IW5, T4, T5, T6)
|
||||
#options GAME(IW3, IW4, IW5, QOS, T4, T5, T6)
|
||||
|
||||
#filename "Game/" + GAME + "/Image/ImageDumper" + GAME + ".h"
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Game/IW3/Image/ImageToCommonConverterIW3.h"
|
||||
#include "Game/IW4/Image/ImageToCommonConverterIW4.h"
|
||||
#include "Game/IW5/Image/ImageToCommonConverterIW5.h"
|
||||
#include "Game/QOS/Image/ImageToCommonConverterQOS.h"
|
||||
#include "Game/T4/Image/ImageToCommonConverterT4.h"
|
||||
#include "Game/T5/Image/ImageToCommonConverterT5.h"
|
||||
#include "Game/T6/Image/ImageToCommonConverterT6.h"
|
||||
@@ -17,6 +18,7 @@ namespace image
|
||||
new ToCommonConverterIW3(),
|
||||
new ToCommonConverterIW4(),
|
||||
new ToCommonConverterIW5(),
|
||||
new ToCommonConverterQOS(),
|
||||
new ToCommonConverterT4(),
|
||||
new ToCommonConverterT5(),
|
||||
new ToCommonConverterT6(),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#options GAME (IW3, IW4, IW5, T4, T5, T6)
|
||||
#options GAME (IW3, IW4, IW5, QOS, T4, T5, T6)
|
||||
|
||||
#filename "Game/" + GAME + "/Image/ImageToCommonConverter" + GAME + ".cpp"
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#define FEATURE_IW5
|
||||
#define DX9
|
||||
#define IWI8
|
||||
#elif GAME == "QOS"
|
||||
#define FEATURE_QOS
|
||||
#define DX9
|
||||
#define IWI6
|
||||
#elif GAME == "T4"
|
||||
#define FEATURE_T4
|
||||
#define DX9
|
||||
@@ -82,7 +86,7 @@ namespace
|
||||
#endif
|
||||
|
||||
const auto& loadDef = *image.texture.loadDef;
|
||||
#if defined(FEATURE_IW3) || defined(FEATURE_T4)
|
||||
#if defined(FEATURE_IW3) || defined(FEATURE_QOS) || defined(FEATURE_T4)
|
||||
textureLoader.Width(loadDef.dimensions[0]).Height(loadDef.dimensions[1]).Depth(loadDef.dimensions[2]);
|
||||
#else
|
||||
textureLoader.Width(image.width).Height(image.height).Depth(image.depth);
|
||||
@@ -106,6 +110,10 @@ namespace
|
||||
|
||||
#ifdef DX9
|
||||
textureLoader.Format(static_cast<oat::D3DFORMAT>(loadDef.format));
|
||||
#ifdef FEATURE_QOS
|
||||
// The QOS executable uploads embedded load-def mip data from the smallest mip to the largest.
|
||||
textureLoader.MipMapOrder(Dx9TextureLoader::MipMapDataOrder::SmallestToLargest);
|
||||
#endif
|
||||
#else
|
||||
textureLoader.Format(static_cast<oat::DXGI_FORMAT>(loadDef.format));
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#options GAME(IW3, IW4, IW5, T4, T5, T6)
|
||||
#options GAME(IW3, IW4, IW5, QOS, T4, T5, T6)
|
||||
|
||||
#filename "Game/" + GAME + "/Image/ImageToCommonConverter" + GAME + ".h"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#options GAME (IW3, IW4, IW5, T4, T5, T6)
|
||||
#options GAME (IW3, IW4, IW5, QOS, T4, T5, T6)
|
||||
|
||||
#filename "Game/" + GAME + "/Maps/MapEntsDumper" + GAME + ".cpp"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#options GAME (IW3, IW4, IW5, T4, T5, T6)
|
||||
#options GAME (IW3, IW4, IW5, QOS, T4, T5, T6)
|
||||
|
||||
#filename "Game/" + GAME + "/Maps/MapEntsDumper" + GAME + ".h"
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Game/IW3/ObjWriterIW3.h"
|
||||
#include "Game/IW4/ObjWriterIW4.h"
|
||||
#include "Game/IW5/ObjWriterIW5.h"
|
||||
#include "Game/QOS/ObjWriterQOS.h"
|
||||
#include "Game/T4/ObjWriterT4.h"
|
||||
#include "Game/T5/ObjWriterT5.h"
|
||||
#include "Game/T6/ObjWriterT6.h"
|
||||
@@ -45,6 +46,7 @@ IObjWriter* IObjWriter::GetObjWriterForGame(GameId game)
|
||||
new IW3::ObjWriter(),
|
||||
new IW4::ObjWriter(),
|
||||
new IW5::ObjWriter(),
|
||||
new QOS::ObjWriter(),
|
||||
new T4::ObjWriter(),
|
||||
new T5::ObjWriter(),
|
||||
new T6::ObjWriter(),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#options GAME (IW3, IW4, IW5, T4, T5, T6)
|
||||
#options GAME (IW3, IW4, IW5, QOS, T4, T5, T6)
|
||||
|
||||
#filename "Game/" + GAME + "/XModel/XModelDumper" + GAME + ".cpp"
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
#elif GAME == "IW5"
|
||||
#define FEATURE_IW5
|
||||
#define GAME_LOWER "iw5"
|
||||
#elif GAME == "QOS"
|
||||
#define FEATURE_QOS
|
||||
#define GAME_LOWER "qos"
|
||||
#elif GAME == "T4"
|
||||
#define FEATURE_T4
|
||||
#define GAME_LOWER "t4"
|
||||
@@ -334,7 +337,7 @@ namespace
|
||||
return false;
|
||||
|
||||
const auto& vertList = surface.vertList[0];
|
||||
#if defined(FEATURE_IW3) || defined(FEATURE_T4)
|
||||
#if defined(FEATURE_IW3) || defined(FEATURE_QOS) || defined(FEATURE_T4)
|
||||
// IW3 has some models that are missing 1 (a single) tri in its first lod.
|
||||
// It is not contained in any vert list or blend
|
||||
// I think this is a bug (?), so omit anyway.
|
||||
@@ -398,7 +401,7 @@ namespace
|
||||
jXModel.physCollmap = AssetName(model.physCollmap->name);
|
||||
#endif
|
||||
|
||||
#if defined(FEATURE_T4) || defined(FEATURE_T5) || defined(FEATURE_T6)
|
||||
#if defined(FEATURE_QOS) || defined(FEATURE_T4) || defined(FEATURE_T5) || defined(FEATURE_T6)
|
||||
if (model.physConstraints && model.physConstraints->name)
|
||||
jXModel.physConstraints = AssetName(model.physConstraints->name);
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#options GAME (IW3, IW4, IW5, T4, T5, T6)
|
||||
#options GAME (IW3, IW4, IW5, QOS, T4, T5, T6)
|
||||
|
||||
#filename "Game/" + GAME + "/XModel/XModelDumper" + GAME + ".h"
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Game/IW3/XModel/XModelToCommonConverterIW3.h"
|
||||
#include "Game/IW4/XModel/XModelToCommonConverterIW4.h"
|
||||
#include "Game/IW5/XModel/XModelToCommonConverterIW5.h"
|
||||
#include "Game/QOS/XModel/XModelToCommonConverterQOS.h"
|
||||
#include "Game/T4/XModel/XModelToCommonConverterT4.h"
|
||||
#include "Game/T5/XModel/XModelToCommonConverterT5.h"
|
||||
#include "Game/T6/XModel/XModelToCommonConverterT6.h"
|
||||
@@ -17,6 +18,7 @@ namespace xmodel
|
||||
new ToCommonConverterIW3(),
|
||||
new ToCommonConverterIW4(),
|
||||
new ToCommonConverterIW5(),
|
||||
new ToCommonConverterQOS(),
|
||||
new ToCommonConverterT4(),
|
||||
new ToCommonConverterT5(),
|
||||
new ToCommonConverterT6(),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#options GAME (IW3, IW4, IW5, T4, T5, T6)
|
||||
#options GAME (IW3, IW4, IW5, QOS, T4, T5, T6)
|
||||
|
||||
#filename "Game/" + GAME + "/XModel/XModelToCommonConverter" + GAME + ".cpp"
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#define FEATURE_IW4
|
||||
#elif GAME == "IW5"
|
||||
#define FEATURE_IW5
|
||||
#elif GAME == "QOS"
|
||||
#define FEATURE_QOS
|
||||
#elif GAME == "T4"
|
||||
#define FEATURE_T4
|
||||
#elif GAME == "T5"
|
||||
@@ -34,6 +36,7 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
#include <string_view>
|
||||
|
||||
using namespace GAME;
|
||||
|
||||
@@ -56,7 +59,7 @@ namespace
|
||||
{
|
||||
MaterialTextureDef* def = &material->textureTable[textureIndex];
|
||||
|
||||
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5) || defined(FEATURE_T4)
|
||||
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_IW5) || defined(FEATURE_QOS) || defined(FEATURE_T4)
|
||||
if (def->semantic == TS_COLOR_MAP)
|
||||
potentialTextureDefs.push_back(def);
|
||||
#else
|
||||
@@ -70,6 +73,32 @@ namespace
|
||||
if (potentialTextureDefs.size() == 1)
|
||||
return GetImageFromTextureDef(*potentialTextureDefs[0]);
|
||||
|
||||
#ifdef FEATURE_QOS
|
||||
// QoS can tag helper maps like *_edge as TS_COLOR_MAP; prefer diffuse-style names when several candidates exist.
|
||||
GfxImage* qosFallback = nullptr;
|
||||
for (const auto* def : potentialTextureDefs)
|
||||
{
|
||||
auto* image = GetImageFromTextureDef(*def);
|
||||
if (!image || !image->name)
|
||||
continue;
|
||||
|
||||
auto name = std::string_view(image->name);
|
||||
while (!name.empty() && (name.front() == ',' || name.front() == '*'))
|
||||
name.remove_prefix(1);
|
||||
|
||||
if (name.ends_with("_c") || name.ends_with("_col") || name.ends_with("_color") || name.ends_with("_diff"))
|
||||
return image;
|
||||
|
||||
if (!qosFallback && !name.ends_with("_edge") && !name.ends_with("_print") && !name.ends_with("_prsz")
|
||||
&& name.find("_edge_") == std::string_view::npos)
|
||||
{
|
||||
qosFallback = image;
|
||||
}
|
||||
}
|
||||
if (qosFallback)
|
||||
return qosFallback;
|
||||
#endif
|
||||
|
||||
for (const auto* def : potentialTextureDefs)
|
||||
{
|
||||
if (tolower(def->nameStart) == 'c' && tolower(def->nameEnd) == 'p')
|
||||
@@ -180,7 +209,7 @@ namespace
|
||||
return false;
|
||||
|
||||
const auto& vertList = surface.vertList[0];
|
||||
#if defined(FEATURE_IW3) || defined(FEATURE_T4)
|
||||
#if defined(FEATURE_IW3) || defined(FEATURE_QOS) || defined(FEATURE_T4)
|
||||
// IW3 has some models that are missing 1 (a single) tri in its first lod.
|
||||
// It is not contained in any vert list or blend
|
||||
// I think this is a bug (?), so omit anyway.
|
||||
@@ -298,9 +327,12 @@ namespace
|
||||
if (colorMap)
|
||||
xMaterial.colorMapName = AssetName(colorMap->name);
|
||||
|
||||
#ifndef FEATURE_QOS
|
||||
// QoS normal map decoding/selection is not verified yet; exporting them makes the preview shading misleading.
|
||||
const auto* normalMap = GetMaterialNormalMap(material);
|
||||
if (normalMap)
|
||||
xMaterial.normalMapName = AssetName(normalMap->name);
|
||||
#endif
|
||||
|
||||
const auto* specularMap = GetMaterialSpecularMap(material);
|
||||
if (specularMap)
|
||||
@@ -346,8 +378,17 @@ namespace
|
||||
vertex.coordinates[1] = v.xyz.y;
|
||||
vertex.coordinates[2] = v.xyz.z;
|
||||
Common::Vec3UnpackUnitVec(v.normal, vertex.normal);
|
||||
#ifdef FEATURE_QOS
|
||||
vertex.color[0] = 1.0f;
|
||||
vertex.color[1] = 1.0f;
|
||||
vertex.color[2] = 1.0f;
|
||||
vertex.color[3] = 1.0f;
|
||||
vertex.uv[0] = v.texCoord.x;
|
||||
vertex.uv[1] = v.texCoord.y;
|
||||
#else
|
||||
Common::Vec4UnpackGfxColor(v.color, vertex.color);
|
||||
Common::Vec2UnpackTexCoords(v.texCoord, vertex.uv);
|
||||
#endif
|
||||
|
||||
out.m_vertices.emplace_back(vertex);
|
||||
}
|
||||
@@ -405,7 +446,7 @@ namespace
|
||||
|
||||
if (surface.vertList)
|
||||
{
|
||||
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_T4)
|
||||
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_QOS) || defined(FEATURE_T4)
|
||||
assert(!surface.deformed);
|
||||
#else
|
||||
assert((surface.flags & XSURFACE_FLAG_DEFORMED) == 0);
|
||||
@@ -430,7 +471,7 @@ namespace
|
||||
auto vertsBlendOffset = 0u;
|
||||
if (surface.vertInfo.vertsBlend)
|
||||
{
|
||||
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_T4)
|
||||
#if defined(FEATURE_IW3) || defined(FEATURE_IW4) || defined(FEATURE_QOS) || defined(FEATURE_T4)
|
||||
assert(surface.deformed);
|
||||
#else
|
||||
assert((surface.flags & XSURFACE_FLAG_DEFORMED) > 0);
|
||||
@@ -532,7 +573,7 @@ namespace
|
||||
auto& object = out.m_objects[surfIndex];
|
||||
object.m_faces.reserve(surface.triCount);
|
||||
|
||||
#ifdef FEATURE_T4
|
||||
#if defined(FEATURE_QOS) || defined(FEATURE_T4)
|
||||
// T4 tri indices are local to the surface, while baseVertIndex does not match
|
||||
// the flattened common vertex buffer we build here.
|
||||
auto surfaceVertexOffset = 0u;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#options GAME (IW3, IW4, IW5, T4, T5, T6)
|
||||
#options GAME (IW3, IW4, IW5, QOS, T4, T5, T6)
|
||||
|
||||
#filename "Game/" + GAME + "/XModel/XModelToCommonConverter" + GAME + ".h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user