Fixed ray casting on meshes with textures.

This commit is contained in:
Leonardo Zide 2024-12-20 13:14:38 -08:00
parent 6ab237f50a
commit 1df718ecd4
2 changed files with 101 additions and 73 deletions

View file

@ -14,21 +14,6 @@ lcMesh* gPlaceholderMesh;
lcMesh::lcMesh() lcMesh::lcMesh()
{ {
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
{
mLods[LodIdx].Sections = nullptr;
mLods[LodIdx].NumSections = 0;
}
mNumVertices = 0;
mNumTexturedVertices = 0;
mIndexType = 0;
mVertexData = nullptr;
mVertexDataSize = 0;
mIndexData = nullptr;
mIndexDataSize = 0;
mVertexCacheOffset = -1;
mIndexCacheOffset = -1;
} }
lcMesh::~lcMesh() lcMesh::~lcMesh()
@ -164,7 +149,6 @@ void lcMesh::CreateBox()
*Indices++ = 23; *Indices++ = 22; *Indices++ = 21; *Indices++ = 23; *Indices++ = 22; *Indices++ = 21;
*Indices++ = 23; *Indices++ = 21; *Indices++ = 20; *Indices++ = 23; *Indices++ = 21; *Indices++ = 20;
Section = &mLods[LC_MESH_LOD_HIGH].Sections[1]; Section = &mLods[LC_MESH_LOD_HIGH].Sections[1];
Section->ColorIndex = gEdgeColor; Section->ColorIndex = gEdgeColor;
Section->IndexOffset = 36 * 2; Section->IndexOffset = 36 * 2;
@ -193,27 +177,42 @@ bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, floa
if (!lcBoundingBoxRayIntersectDistance(mBoundingBox.Min, mBoundingBox.Max, Start, End, &Distance, nullptr, &IntersectionPlane) || (Distance >= MinDistance)) if (!lcBoundingBoxRayIntersectDistance(mBoundingBox.Min, mBoundingBox.Max, Start, End, &Distance, nullptr, &IntersectionPlane) || (Distance >= MinDistance))
return false; return false;
const lcVertex* const Verts = (lcVertex*)mVertexData;
bool Hit = false; bool Hit = false;
lcVector3 Intersection; lcVector3 Intersection;
for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++) for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++)
{ {
lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx]; const lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx];
if (Section->PrimitiveType != LC_MESH_TRIANGLES && Section->PrimitiveType != LC_MESH_TEXTURED_TRIANGLES) if (Section->PrimitiveType == LC_MESH_TRIANGLES)
continue;
IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
{ {
const lcVector3& v1 = Verts[Indices[Idx]].Position; const lcVertex* Verts = GetVertexData();
const lcVector3& v2 = Verts[Indices[Idx + 1]].Position; const IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
const lcVector3& v3 = Verts[Indices[Idx + 2]].Position;
if (lcLineTriangleMinIntersection(v1, v2, v3, Start, End, &MinDistance, &Intersection)) for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
Hit = true; {
const lcVector3& v1 = Verts[Indices[Idx]].Position;
const lcVector3& v2 = Verts[Indices[Idx + 1]].Position;
const lcVector3& v3 = Verts[Indices[Idx + 2]].Position;
if (lcLineTriangleMinIntersection(v1, v2, v3, Start, End, &MinDistance, &Intersection))
Hit = true;
}
}
else if (Section->PrimitiveType == LC_MESH_TEXTURED_TRIANGLES)
{
const lcVertexTextured* Verts = GetTexturedVertexData();
const IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
{
const lcVector3& v1 = Verts[Indices[Idx]].Position;
const lcVector3& v2 = Verts[Indices[Idx + 1]].Position;
const lcVector3& v3 = Verts[Indices[Idx + 2]].Position;
if (lcLineTriangleMinIntersection(v1, v2, v3, Start, End, &MinDistance, &Intersection))
Hit = true;
}
} }
} }
@ -234,20 +233,28 @@ bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, floa
template<typename IndexType> template<typename IndexType>
bool lcMesh::IntersectsPlanes(const lcVector4 (&Planes)[6]) bool lcMesh::IntersectsPlanes(const lcVector4 (&Planes)[6])
{ {
lcVertex* Verts = (lcVertex*)mVertexData;
for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++) for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++)
{ {
lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx]; const lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx];
if (Section->PrimitiveType != LC_MESH_TRIANGLES && Section->PrimitiveType != LC_MESH_TEXTURED_TRIANGLES) if (Section->PrimitiveType == LC_MESH_TRIANGLES)
continue; {
const lcVertex* Verts = GetVertexData();
const IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType); for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
if (lcTriangleIntersectsPlanes(Verts[Indices[Idx]].Position, Verts[Indices[Idx+1]].Position, Verts[Indices[Idx+2]].Position, Planes))
return true;
}
else if (Section->PrimitiveType == LC_MESH_TEXTURED_TRIANGLES)
{
const lcVertexTextured* Verts = GetTexturedVertexData();
const IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3) for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
if (lcTriangleIntersectsPlanes(Verts[Indices[Idx]].Position, Verts[Indices[Idx+1]].Position, Verts[Indices[Idx+2]].Position, Planes)) if (lcTriangleIntersectsPlanes(Verts[Indices[Idx]].Position, Verts[Indices[Idx+1]].Position, Verts[Indices[Idx+2]].Position, Planes))
return true; return true;
}
} }
return false; return false;
@ -282,33 +289,56 @@ void lcMesh::ExportPOVRay(lcFile& File, const char* MeshName, const char** Color
sprintf(Line, "#declare lc_%s = mesh {\n", MeshName); sprintf(Line, "#declare lc_%s = mesh {\n", MeshName);
File.WriteLine(Line); File.WriteLine(Line);
const lcVertex* const Verts = (lcVertex*)mVertexData;
for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++) for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++)
{ {
lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx]; lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx];
if (Section->PrimitiveType != LC_MESH_TRIANGLES && Section->PrimitiveType != LC_MESH_TEXTURED_TRIANGLES) if (Section->PrimitiveType == LC_MESH_TRIANGLES)
continue;
IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
if (NumSections > 1)
File.WriteLine(" mesh {\n");
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
{ {
const lcVector3 v1 = Verts[Indices[Idx]].Position / 25.0f; const lcVertex* Verts = GetVertexData();
const lcVector3 v2 = Verts[Indices[Idx + 1]].Position / 25.0f; const IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
const lcVector3 v3 = Verts[Indices[Idx + 2]].Position / 25.0f;
const lcVector3 n1 = lcUnpackNormal(Verts[Indices[Idx]].Normal); if (NumSections > 1)
const lcVector3 n2 = lcUnpackNormal(Verts[Indices[Idx + 1]].Normal); File.WriteLine(" mesh {\n");
const lcVector3 n3 = lcUnpackNormal(Verts[Indices[Idx + 2]].Normal);
sprintf(Line, " smooth_triangle { <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g> }\n", for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
-v1.y, -v1.x, v1.z, -n1.y, -n1.x, n1.z, -v2.y, -v2.x, v2.z, -n2.y, -n2.x, n2.z, -v3.y, -v3.x, v3.z, -n3.y, -n3.x, n3.z); {
File.WriteLine(Line); const lcVector3 v1 = Verts[Indices[Idx]].Position / 25.0f;
const lcVector3 v2 = Verts[Indices[Idx + 1]].Position / 25.0f;
const lcVector3 v3 = Verts[Indices[Idx + 2]].Position / 25.0f;
const lcVector3 n1 = lcUnpackNormal(Verts[Indices[Idx]].Normal);
const lcVector3 n2 = lcUnpackNormal(Verts[Indices[Idx + 1]].Normal);
const lcVector3 n3 = lcUnpackNormal(Verts[Indices[Idx + 2]].Normal);
sprintf(Line, " smooth_triangle { <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g> }\n",
-v1.y, -v1.x, v1.z, -n1.y, -n1.x, n1.z, -v2.y, -v2.x, v2.z, -n2.y, -n2.x, n2.z, -v3.y, -v3.x, v3.z, -n3.y, -n3.x, n3.z);
File.WriteLine(Line);
}
} }
else if (Section->PrimitiveType == LC_MESH_TEXTURED_TRIANGLES)
{
const lcVertexTextured* Verts = GetTexturedVertexData();
const IndexType* Indices = (IndexType*)mIndexData + Section->IndexOffset / sizeof(IndexType);
if (NumSections > 1)
File.WriteLine(" mesh {\n");
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
{
const lcVector3 v1 = Verts[Indices[Idx]].Position / 25.0f;
const lcVector3 v2 = Verts[Indices[Idx + 1]].Position / 25.0f;
const lcVector3 v3 = Verts[Indices[Idx + 2]].Position / 25.0f;
const lcVector3 n1 = lcUnpackNormal(Verts[Indices[Idx]].Normal);
const lcVector3 n2 = lcUnpackNormal(Verts[Indices[Idx + 1]].Normal);
const lcVector3 n3 = lcUnpackNormal(Verts[Indices[Idx + 2]].Normal);
sprintf(Line, " smooth_triangle { <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g> }\n",
-v1.y, -v1.x, v1.z, -n1.y, -n1.x, n1.z, -v2.y, -v2.x, v2.z, -n2.y, -n2.x, n2.z, -v3.y, -v3.x, v3.z, -n3.y, -n3.x, n3.z);
File.WriteLine(Line);
}
}
else
continue;
if (Section->ColorIndex != gDefaultColor) if (Section->ColorIndex != gDefaultColor)
{ {

View file

@ -45,8 +45,8 @@ struct lcMeshSection
struct lcMeshLod struct lcMeshLod
{ {
lcMeshSection* Sections; lcMeshSection* Sections = nullptr;
int NumSections; int NumSections = 0;
}; };
enum enum
@ -121,20 +121,18 @@ public:
lcMeshLod mLods[LC_NUM_MESH_LODS]; lcMeshLod mLods[LC_NUM_MESH_LODS];
lcBoundingBox mBoundingBox; lcBoundingBox mBoundingBox;
float mRadius; float mRadius = 0.0f;
lcMeshFlags mFlags; lcMeshFlags mFlags;
void* mVertexData; void* mVertexData = nullptr;
int mVertexDataSize; int mVertexDataSize = 0;
void* mIndexData; void* mIndexData = nullptr;
int mIndexDataSize; int mIndexDataSize = 0;
int mVertexCacheOffset; int mVertexCacheOffset = -1;
int mIndexCacheOffset; int mIndexCacheOffset = -1;
int mNumVertices; int mNumVertices = 0;
int mNumTexturedVertices; int mNumTexturedVertices = 0;
int mConditionalVertexCount; int mConditionalVertexCount = 0;
int mIndexType; int mIndexType = 0;
}; };