Added bounding boxes to mesh sections.

This commit is contained in:
Leonardo Zide 2019-11-22 12:48:40 -08:00
parent 226a4581aa
commit 481d4e6e81
3 changed files with 86 additions and 77 deletions

View file

@ -8,7 +8,7 @@
#include "lc_library.h"
#define LC_MESH_FILE_ID LC_FOURCC('M', 'E', 'S', 'H')
#define LC_MESH_FILE_VERSION 0x0117
#define LC_MESH_FILE_VERSION 0x0118
lcMesh* gPlaceholderMesh;
@ -143,6 +143,8 @@ void lcMesh::CreateBox()
Section->NumIndices = 36;
Section->PrimitiveType = LC_MESH_TRIANGLES;
Section->Texture = nullptr;
Section->BoundingBox = mBoundingBox;
Section->Radius = mRadius;
*Indices++ = 0; *Indices++ = 1; *Indices++ = 2;
*Indices++ = 0; *Indices++ = 2; *Indices++ = 3;
@ -169,6 +171,8 @@ void lcMesh::CreateBox()
Section->NumIndices = 24;
Section->PrimitiveType = LC_MESH_LINES;
Section->Texture = nullptr;
Section->BoundingBox = mBoundingBox;
Section->Radius = mRadius;
*Indices++ = 0; *Indices++ = 1; *Indices++ = 1; *Indices++ = 2;
*Indices++ = 2; *Indices++ = 3; *Indices++ = 3; *Indices++ = 0;
@ -402,6 +406,9 @@ bool lcMesh::FileLoad(lcMemFile& File)
Section.IndexOffset = IndexOffset;
Section.NumIndices = NumIndices;
Section.PrimitiveType = (lcMeshPrimitiveType)PrimtiveType;
Section.BoundingBox.Min = File.ReadVector3();
Section.BoundingBox.Max = File.ReadVector3();
Section.Radius = File.ReadFloat();
if (!File.ReadU16(&Length, 1))
return false;
@ -460,6 +467,9 @@ bool lcMesh::FileSave(lcMemFile& File)
File.WriteU32(Section.IndexOffset);
File.WriteU32(Section.NumIndices);
File.WriteU16(Section.PrimitiveType);
File.WriteVector3(Section.BoundingBox.Min);
File.WriteVector3(Section.BoundingBox.Max);
File.WriteFloat(Section.Radius);
if (Section.Texture)
{

View file

@ -31,6 +31,8 @@ struct lcMeshSection
int NumIndices;
lcMeshPrimitiveType PrimitiveType;
lcTexture* Texture;
lcBoundingBox BoundingBox;
float Radius;
};
struct lcMeshLod

View file

@ -1000,8 +1000,6 @@ lcMesh* lcLibraryMeshData::CreateMesh()
Mesh->Create(NumSections, NumVertices, NumTexturedVertices, NumIndices);
lcVertex* DstVerts = (lcVertex*)Mesh->mVertexData;
lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
bool UpdatedBoundingBox = false;
if (!mHasTextures)
{
@ -1016,21 +1014,6 @@ lcMesh* lcLibraryMeshData::CreateMesh()
DstVertex.Position = lcVector3LDrawToLeoCAD(SrcVertex.Position);
DstVertex.Normal = lcPackNormal(lcVector3LDrawToLeoCAD(SrcVertex.Normal));
}
for (const lcLibraryMeshSection* Section : mSections[MeshDataIdx])
{
if (Section->mPrimitiveType != LC_MESH_TRIANGLES)
continue;
UpdatedBoundingBox = true;
for (quint32 Index : Section->mIndices)
{
lcVector3 Position = lcVector3LDrawToLeoCAD(Vertices[Index].Position);
Min = lcMin(Min, Position);
Max = lcMax(Max, Position);
}
}
}
}
else
@ -1063,31 +1046,17 @@ lcMesh* lcLibraryMeshData::CreateMesh()
DstVertex.Position = lcVector3LDrawToLeoCAD(SrcVertex.Position);
DstVertex.Normal = lcPackNormal(lcVector3LDrawToLeoCAD(SrcVertex.Normal));
DstVertex.TexCoord = SrcVertex.TexCoord;
lcVector3& Position = DstVertex.Position;
Min = lcMin(Min, Position);
Max = lcMax(Max, Position);
}
}
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
{
const lcArray<lcLibraryMeshVertex>& Vertices = mVertices[MeshDataIdx];
for (lcLibraryMeshSection* Section : mSections[MeshDataIdx])
{
if (Section->mPrimitiveType == LC_MESH_TRIANGLES)
{
UpdatedBoundingBox = true;
for (quint32& Index : Section->mIndices)
{
lcVector3 Position = lcVector3LDrawToLeoCAD(Vertices[Index].Position);
Min = lcMin(Min, Position);
Max = lcMax(Max, Position);
Index = IndexRemap[MeshDataIdx][Index];
}
}
else
{
@ -1106,13 +1075,6 @@ lcMesh* lcLibraryMeshData::CreateMesh()
}
}
if (!UpdatedBoundingBox)
Min = Max = lcVector3(0.0f, 0.0f, 0.0f);
Mesh->mBoundingBox.Max = Max;
Mesh->mBoundingBox.Min = Min;
Mesh->mRadius = lcLength((Max - Min) / 2.0f);
NumIndices = 0;
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
@ -1228,57 +1190,92 @@ lcMesh* lcLibraryMeshData::CreateMesh()
if (mHasLogoStud)
Mesh->mFlags |= lcMeshFlag::HasLogoStud;
/*
for (int SectionIdx = 0; SectionIdx < mSections.GetSize(); SectionIdx++)
lcVector3 MeshMin(FLT_MAX, FLT_MAX, FLT_MAX), MeshMax(-FLT_MAX, -FLT_MAX, -FLT_MAX);
bool UpdatedBoundingBox = false;
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
{
lcMeshSection& DstSection = Mesh->mSections[SectionIdx];
lcLibraryMeshSection* SrcSection = mSections[SectionIdx];
lcMeshLod& Lod = Mesh->mLods[LodIdx];
DstSection.ColorIndex = SrcSection->mColor;
DstSection.PrimitiveType = SrcSection->mPrimitiveType;
DstSection.NumIndices = SrcSection->mIndices.GetSize();
DstSection.Texture = SrcSection->mTexture;
if (DstSection.Texture)
DstSection.Texture->AddRef();
if (Mesh->mNumVertices < 0x10000)
for (int SectionIdx = 0; SectionIdx < Lod.NumSections; SectionIdx++)
{
DstSection.IndexOffset = NumIndices * 2;
lcMeshSection& Section = Lod.Sections[SectionIdx];
lcVector3 SectionMin(FLT_MAX, FLT_MAX, FLT_MAX), SectionMax(-FLT_MAX, -FLT_MAX, -FLT_MAX);
quint16* Index = (quint16*)Mesh->mIndexData + NumIndices;
if (Mesh->mNumVertices < 0x10000)
{
const quint16* IndexBuffer = static_cast<quint16*>(Mesh->mIndexData) + Section.IndexOffset / 2;
for (int IndexIdx = 0; IndexIdx < DstSection.NumIndices; IndexIdx++)
*Index++ = SrcSection->mIndices[IndexIdx];
}
else
{
DstSection.IndexOffset = NumIndices * 4;
if (!Section.Texture)
{
const lcVertex* VertexBuffer = static_cast<lcVertex*>(Mesh->mVertexData);
quint32* Index = (quint32*)Mesh->mIndexData + NumIndices;
for (int Index = 0; Index < Section.NumIndices; Index++)
{
const lcVector3& Position = VertexBuffer[IndexBuffer[Index]].Position;
SectionMin = lcMin(SectionMin, Position);
SectionMax = lcMax(SectionMax, Position);
}
}
else
{
const lcVertexTextured* VertexBuffer = reinterpret_cast<lcVertexTextured*>(static_cast<char*>(Mesh->mVertexData) + Mesh->mNumVertices * sizeof(lcVertex));
for (int IndexIdx = 0; IndexIdx < DstSection.NumIndices; IndexIdx++)
*Index++ = SrcSection->mIndices[IndexIdx];
}
if (DstSection.PrimitiveType == LC_MESH_TRIANGLES || DstSection.PrimitiveType == LC_MESH_TEXTURED_TRIANGLES)
{
if (DstSection.ColorIndex == gDefaultColor)
Info->mFlags |= LC_PIECE_HAS_DEFAULT;
for (int Index = 0; Index < Section.NumIndices; Index++)
{
const lcVector3& Position = VertexBuffer[IndexBuffer[Index]].Position;
SectionMin = lcMin(SectionMin, Position);
SectionMax = lcMax(SectionMax, Position);
}
}
}
else
{
if (lcIsColorTranslucent(DstSection.ColorIndex))
Info->mFlags |= LC_PIECE_HAS_TRANSLUCENT;
const quint32* IndexBuffer = static_cast<quint32*>(Mesh->mIndexData) + Section.IndexOffset / 4;
if (!Section.Texture)
{
const lcVertex* VertexBuffer = static_cast<lcVertex*>(Mesh->mVertexData);
for (int Index = 0; Index < Section.NumIndices; Index++)
{
const lcVector3& Position = VertexBuffer[IndexBuffer[Index]].Position;
SectionMin = lcMin(SectionMin, Position);
SectionMax = lcMax(SectionMax, Position);
}
}
else
Info->mFlags |= LC_PIECE_HAS_SOLID;
{
const lcVertexTextured* VertexBuffer = static_cast<lcVertexTextured*>(Mesh->mVertexData);
for (int Index = 0; Index < Section.NumIndices; Index++)
{
const lcVector3& Position = VertexBuffer[IndexBuffer[Index]].Position;
SectionMin = lcMin(SectionMin, Position);
SectionMax = lcMax(SectionMax, Position);
}
}
}
Section.BoundingBox.Max = SectionMax;
Section.BoundingBox.Min = SectionMin;
Section.Radius = lcLength((SectionMax - SectionMin) / 2.0f);
if (Section.PrimitiveType == LC_MESH_TRIANGLES || Section.PrimitiveType == LC_MESH_TEXTURED_TRIANGLES)
{
UpdatedBoundingBox = true;
MeshMin = lcMin(SectionMin, MeshMin);
MeshMax = lcMax(SectionMax, MeshMax);
}
}
else
Info->mFlags |= LC_PIECE_HAS_LINES;
NumIndices += DstSection.NumIndices;
}
*/
if (!UpdatedBoundingBox)
MeshMin = MeshMax = lcVector3(0.0f, 0.0f, 0.0f);
Mesh->mBoundingBox.Max = MeshMax;
Mesh->mBoundingBox.Min = MeshMin;
Mesh->mRadius = lcLength((MeshMax - MeshMin) / 2.0f);
return Mesh;
}