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

View file

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

View file

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