Skip to content

Commit

Permalink
Fix 32-bit GPU vertex buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
VenoMKO committed Jan 29, 2022
1 parent 582cef6 commit 7184e73
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 16 deletions.
2 changes: 2 additions & 0 deletions Core/Tera/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ static const unsigned int BUILD_NUMBER = (
// GPU buffer has lower quality due to packed positions and half precision UVs,
// so its better to use CPU buffer instead. (Tera uses GPU buffer to render models)
#define USE_GPU_VERTEX_BUFFER 0
// Build and save SkelMesh's raw points index buffers
#define SAVE_RAWINDICES 0

#if _DEBUG
// DUMP_PATH should be set in the ENV
Expand Down
59 changes: 55 additions & 4 deletions Core/Tera/USkeletalMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,20 +423,49 @@ void FStaticLODModel::Serialize(FStream& s, UObject* owner, int32 idx)

s << RequiredBones;

#if SAVE_RAWINDICES
if (s.GetFV() == VER_TERA_CLASSIC)
{
if (!s.IsReading() && RawPointIndices.GetElementCount())
{
LegacyRawPointIndices.Realloc(RawPointIndices.GetElementCount());
uint16* dst = (uint16*)LegacyRawPointIndices.GetAllocation();
uint32* src = (uint32*)RawPointIndices.GetAllocation();
for (int32 idx = 0; idx < RawPointIndices.GetElementCount(); ++idx)
{
memcpy(&dst[idx], &src[idx], LegacyRawPointIndices.GetElementSize());
}
}
LegacyRawPointIndices.Serialize(s, owner);
RawPointIndices.Realloc(LegacyRawPointIndices.GetElementCount());
for (int32 idx = 0; idx < LegacyRawPointIndices.GetElementCount(); ++idx)
if (s.IsReading())
{
int32 v = *(uint16*)LegacyRawPointIndices.GetAllocation() + (idx * LegacyRawPointIndices.GetElementSize());
memcpy((uint8*)RawPointIndices.GetAllocation() + (idx * RawPointIndices.GetElementSize()), &v, RawPointIndices.GetElementSize());
RawPointIndices.Realloc(LegacyRawPointIndices.GetElementCount());
uint32* dst = (uint32*)RawPointIndices.GetAllocation();
uint16* src = (uint16*)LegacyRawPointIndices.GetAllocation();
for (int32 idx = 0; idx < RawPointIndices.GetElementCount(); ++idx)
{
uint32 item = (uint32)src[idx];
memcpy(&dst[idx], &item, RawPointIndices.GetElementSize());
}
}
}
else
{
RawPointIndices.Serialize(s, owner);
}
#else
// Raw point indices are useless. Save disk space by discarding them.
if (s.GetFV() == VER_TERA_CLASSIC)
{
FWordBulkData tmp;
tmp.Serialize(s, owner);
}
else
{
FIntBulkData tmp;
tmp.Serialize(s, owner);
}
#endif

if (s.GetFV() > VER_TERA_CLASSIC)
{
Expand Down Expand Up @@ -554,6 +583,15 @@ void FGPUSkinVertexBase::Serialize(FStream& s)
}
}

void FGPUSkinVertexBase::Serialize(FStream& s, FVector& pos)
{
if (s.GetFV() == VER_TERA_CLASSIC)
{
s << pos;
}
Serialize(s);
}

bool USkeletalMesh::RegisterProperty(FPropertyTag* property)
{
if (PROP_IS(property, bHasVertexColors))
Expand Down Expand Up @@ -1191,6 +1229,15 @@ bool USkeletalMesh::AcceptVisitor(MeshTravallerData* importData, uint32 lodIdx,
delete sectionIndexBufferArray[sectionIndex];
}

#if SAVE_RAWINDICES
lod.RawPointIndices.Realloc(rawPointIndices.size());
memcpy(lod.RawPointIndices.GetAllocation(), &rawPointIndices.front(), lod.RawPointIndices.GetElementCount()* lod.RawPointIndices.GetElementSize());
#endif

if (GetPackage()->GetFileVersion() == VER_TERA_CLASSIC)
{
lod.VertexBufferGPUSkin.bUsePackedPosition = false;
}
lod.VertexBufferGPUSkin.ElementCount = lod.NumVertices;
lod.VertexBufferGPUSkin.AllocateBuffer();

Expand All @@ -1211,6 +1258,10 @@ bool USkeletalMesh::AcceptVisitor(MeshTravallerData* importData, uint32 lodIdx,
{
// Old skeleton may not match the new one, thus all LODs are invalid. Remove them.
LodModels.resize(1);
if (LODInfo)
{
LODInfo->resize(1);
}
lodIdx = 0;
}

Expand Down
39 changes: 28 additions & 11 deletions Core/Tera/USkeletalMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ struct FGPUSkinVertexBase {
uint8 BoneWeight[MAX_INFLUENCES];

void Serialize(FStream& s);
void Serialize(FStream& s, FVector& pos);
};

template<uint32 NumTexCoords = 1>
Expand All @@ -216,9 +217,15 @@ struct FGPUSkinVertexFloatAABB : public FGPUSkinVertexBase {

friend FStream& operator<<(FStream& s, FGPUSkinVertexFloatAABB& v)
{
v.Serialize(s);

s << v.Position;
if (s.GetFV() == VER_TERA_CLASSIC)
{
v.Serialize(s, v.Position);
}
else
{
v.Serialize(s);
s << v.Position;
}

for (int32 idx = 0; idx < NumTexCoords; ++idx)
{
Expand All @@ -236,8 +243,10 @@ struct FGPUSkinVertexFloatAAB : public FGPUSkinVertexBase {
friend FStream& operator<<(FStream& s, FGPUSkinVertexFloatAAB& v)
{
v.Serialize(s);

s << v.Position;
if (s.GetFV() > VER_TERA_CLASSIC)
{
s << v.Position;
}

for (int32 idx = 0; idx < NumTexCoords; ++idx)
{
Expand All @@ -254,9 +263,15 @@ struct FGPUSkinVertexFloatABB : public FGPUSkinVertexBase {

friend FStream& operator<<(FStream& s, FGPUSkinVertexFloatABB& v)
{
v.Serialize(s);

s << v.Position;
if (s.GetFV() == VER_TERA_CLASSIC)
{
v.Serialize(s, v.Position);
}
else
{
v.Serialize(s);
s << v.Position;
}

for (int32 idx = 0; idx < NumTexCoords; ++idx)
{
Expand All @@ -274,8 +289,10 @@ struct FGPUSkinVertexFloatAB : public FGPUSkinVertexBase {
friend FStream& operator<<(FStream& s, FGPUSkinVertexFloatAB& v)
{
v.Serialize(s);

s << v.Position;
if (s.GetFV() > VER_TERA_CLASSIC)
{
s << v.Position;
}

for (int32 idx = 0; idx < NumTexCoords; ++idx)
{
Expand Down Expand Up @@ -327,7 +344,7 @@ struct FSkeletalMeshVertexBuffer {

bool bDisableCompression = false;
bool bUseFullPrecisionUVs = false;
bool bUsePackedPosition = true;
bool bUsePackedPosition = true; // 32-bit client does NOT support packed positions!

uint32 NumVertices = 0;
uint32 NumTexCoords = 1;
Expand Down
2 changes: 1 addition & 1 deletion Core/Utils/FbxUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1838,7 +1838,7 @@ bool FbxUtils::ExportSkeletalMesh(USkeletalMesh* sourceMesh, MeshExportContext&
{
for (int influenceIndex = 0; influenceIndex < MAX_INFLUENCES; influenceIndex++)
{
uint16 influenceBone = v.BoneMap->at(v.InfluenceBones[influenceIndex]);
uint16 influenceBone = v.BoneMap ? v.BoneMap->at(v.InfluenceBones[influenceIndex]) : v.InfluenceBones[influenceIndex];
float w = (float)v.InfluenceWeights[influenceIndex];
float influenceWeight = w / 255.0f;

Expand Down

0 comments on commit 7184e73

Please sign in to comment.