Added fog to the collision shader, made changes to enable rendering different collision materials separately (also, murry crimmas)

This commit is contained in:
parax0
2016-12-25 14:47:59 -07:00
parent c0fb54888d
commit 78baa42bce
7 changed files with 118 additions and 34 deletions

View File

@@ -1,6 +1,7 @@
#include "CCollisionMesh.h"
#include "Core/Render/CRenderer.h"
#include "Core/Render/CDrawUtil.h"
#include <Common/Assert.h>
CCollisionMesh::CCollisionMesh()
{
@@ -31,20 +32,39 @@ void CCollisionMesh::BufferGL()
mBuffered = false;
}
// Add all the relevant indices to the IBO
mVBO.Reserve(mCollisionFaces.size() * 3);
mIBO.Reserve(mCollisionFaces.size() * 3);
// Create new list of collision faces sorted by material index
std::vector<CCollisionFace> SortedTris = mCollisionFaces;
std::sort(SortedTris.begin(), SortedTris.end(), [](CCollisionFace& rLeft, CCollisionFace& rRight) -> bool {
return rLeft.MaterialIdx < rRight.MaterialIdx;
});
for (u32 iVtx = 0; iVtx < mCollisionFaces.size(); iVtx++)
// Add all the relevant indices to the IBO
mVBO.Reserve(SortedTris.size() * 3);
mIBO.Reserve(SortedTris.size() * 3);
mMaterialOffsets.reserve(mMaterials.size());
u32 CurMat = 0;
for (u32 iTri = 0; iTri < SortedTris.size(); iTri++)
{
u16 Verts[3];
CCollisionFace *pFace = &mCollisionFaces[iVtx];
CCollisionFace *pFace = &SortedTris[iTri];
CCollisionLine *pLineA = GetLine(pFace->Lines[0]);
CCollisionLine *pLineB = GetLine(pFace->Lines[1]);
Verts[0] = pLineA->Vertices[0];
Verts[1] = pLineA->Vertices[1];
// Check if we've reached a new material
if (pFace->MaterialIdx != CurMat)
{
while (CurMat != pFace->MaterialIdx)
{
mMaterialOffsets.push_back(mIBO.GetSize());
CurMat++;
}
}
// We have two vertex indices; the last one is one of the ones on line B, but we're not sure which one
if ((pLineB->Vertices[0] != Verts[0]) &&
(pLineB->Vertices[0] != Verts[1]))
@@ -53,7 +73,7 @@ void CCollisionMesh::BufferGL()
Verts[2] = pLineB->Vertices[1];
// Some faces have a property that indicates they need to be inverted
if (pFace->Properties.Invert)
if (GetMaterial(pFace->MaterialIdx).FlippedTri)
{
u16 V0 = Verts[0];
Verts[0] = Verts[2];
@@ -79,6 +99,14 @@ void CCollisionMesh::BufferGL()
}
}
while (CurMat != mMaterials.size())
{
mMaterialOffsets.push_back(mIBO.GetSize());
CurMat++;
}
ASSERT(mMaterialOffsets.size() == mMaterials.size());
// Buffer, and done
mVBO.Buffer();
mIBO.Buffer();
@@ -94,6 +122,18 @@ void CCollisionMesh::Draw()
mVBO.Unbind();
}
void CCollisionMesh::DrawMaterial(u32 MatIdx)
{
if (!mBuffered) BufferGL();
ASSERT(MatIdx < mMaterials.size());
mVBO.Bind();
u32 StartIdx = (MatIdx == 0 ? 0 : mMaterialOffsets[MatIdx - 1]);
u32 NumElements = mMaterialOffsets[MatIdx] - StartIdx;
mIBO.DrawElements(StartIdx, NumElements);
mVBO.Unbind();
}
void CCollisionMesh::DrawWireframe()
{
CDrawUtil::UseColorShader(CColor::skBlack);

View File

@@ -6,6 +6,17 @@
#include "Core/OpenGL/CIndexBuffer.h"
#include <Math/CAABox.h>
struct SCollisionMaterial
{
// todo: figure out what the other properties are
u64 RawFlags;
bool AiWalkThru;
bool FlippedTri;
bool ShootThru;
bool CameraThru;
bool Solid;
};
class CCollisionMesh
{
friend class CCollisionLoader;
@@ -30,30 +41,24 @@ class CCollisionMesh
SOctreeNode* mpRoot;
};
struct SCollisionProperties
{
// todo: figure out what the other properties are
bool Invert;
};
class CCollisionVertex
{
public:
SCollisionProperties Properties;
u32 MaterialIdx;
CVector3f Pos;
};
class CCollisionLine
{
public:
SCollisionProperties Properties;
u32 MaterialIdx;
u16 Vertices[2];
};
class CCollisionFace
{
public:
SCollisionProperties Properties;
u32 MaterialIdx;
u16 Lines[3];
};
@@ -66,10 +71,11 @@ class CCollisionMesh
CAABox mAABox;
CCollisionOctree *mpOctree;
std::vector<u32> mFlags;
std::vector<SCollisionMaterial> mMaterials;
std::vector<CCollisionVertex> mCollisionVertices;
std::vector<CCollisionLine> mCollisionLines;
std::vector<CCollisionFace> mCollisionFaces;
std::vector<u32> mMaterialOffsets;
bool mOctreeLoaded;
CCollisionVertex *GetVertex(u16 Index);
@@ -82,7 +88,11 @@ public:
void BufferGL();
void Draw();
void DrawMaterial(u32 MatIdx);
void DrawWireframe();
inline u32 NumMaterials() const { return mMaterials.size(); }
inline SCollisionMaterial& GetMaterial(u32 Index) { return mMaterials[Index]; }
};
#endif // CCOLLISIONMESH_H

View File

@@ -38,27 +38,27 @@ void CCollisionLoader::ParseOBBNode(IInputStream& rDCLN)
void CCollisionLoader::ReadPropertyFlags(IInputStream& rSrc)
{
CCollisionMesh::SCollisionProperties Property;
SCollisionMaterial Material;
if (mVersion == ePrime)
{
u32 Flag = rSrc.ReadLong();
Property.Invert = (Flag >> 25) & 0x1;
Material.RawFlags = rSrc.ReadLong();
Material.FlippedTri = (Material.RawFlags >> 25) & 0x1;
}
else if (mVersion == eEchoes)
{
u64 Flag = rSrc.ReadLongLong();
Property.Invert = (Flag >> 24) & 0x1;
Material.RawFlags = rSrc.ReadLongLong();
Material.FlippedTri = (Material.RawFlags >> 24) & 0x1;
}
else if (mVersion == eReturns)
{
u64 Flag = rSrc.ReadLongLong();
Property.Invert = (Flag >> 28) & 0x1;
Material.RawFlags = rSrc.ReadLongLong();
Material.FlippedTri = (Material.RawFlags >> 28) & 0x1;
}
mProperties.push_back(Property);
mpMesh->mMaterials.push_back(Material);
}
void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox)
@@ -89,7 +89,7 @@ void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox
CCollisionMesh::CCollisionLine *pLine = &mpMesh->mCollisionLines[iLine];
pLine->Vertices[0] = rFile.ReadShort();
pLine->Vertices[1] = rFile.ReadShort();
pLine->Properties = mProperties[LineIndices[iLine]];
pLine->MaterialIdx = LineIndices[iLine];
}
// Faces
@@ -102,7 +102,7 @@ void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox
pFace->Lines[0] = rFile.ReadShort();
pFace->Lines[1] = rFile.ReadShort();
pFace->Lines[2] = rFile.ReadShort();
pFace->Properties = mProperties[FaceIndices[iFace]];
pFace->MaterialIdx = FaceIndices[iFace];
}
// Echoes introduces a new data chunk; don't know what it is yet, skipping for now
@@ -121,7 +121,7 @@ void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox
{
CCollisionMesh::CCollisionVertex *pVtx = &mpMesh->mCollisionVertices[iVtx];
pVtx->Pos = CVector3f(rFile);
pVtx->Properties = mProperties[VtxIndices[iVtx]];
pVtx->MaterialIdx = VtxIndices[iVtx];
if (BuildAABox) Bounds.ExpandBounds(pVtx->Pos);
}
if (BuildAABox) mpMesh->mAABox = Bounds;

View File

@@ -10,7 +10,6 @@ class CCollisionLoader
TResPtr<CCollisionMeshGroup> mpGroup;
CCollisionMesh *mpMesh;
EGame mVersion;
std::vector<CCollisionMesh::SCollisionProperties> mProperties;
CCollisionLoader();
CCollisionMesh::CCollisionOctree* ParseOctree(IInputStream& rSrc);