mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-21 10:49:23 +00:00
Merge branch 'master' into ContentExporting
This commit is contained in:
@@ -183,6 +183,7 @@ HEADERS += \
|
||||
Render/EDepthGroup.h \
|
||||
Scene/CScriptAttachNode.h \
|
||||
ScriptExtra/CSandwormExtra.h \
|
||||
Resource/CCollisionMaterial.h \
|
||||
GameProject/CGameProject.h \
|
||||
GameProject/CPackage.h \
|
||||
GameProject/CGameExporter.h \
|
||||
@@ -298,6 +299,7 @@ SOURCES += \
|
||||
Resource/Model/EVertexAttribute.cpp \
|
||||
Scene/CScriptAttachNode.cpp \
|
||||
ScriptExtra/CSandwormExtra.cpp \
|
||||
Resource/CCollisionMaterial.cpp \
|
||||
GameProject/CGameProject.cpp \
|
||||
GameProject/CGameExporter.cpp \
|
||||
GameProject/CResourceStore.cpp \
|
||||
|
||||
@@ -329,15 +329,23 @@ void CDrawUtil::UseTextureShader(const CColor& TintColor)
|
||||
CMaterial::KillCachedMaterial();
|
||||
}
|
||||
|
||||
void CDrawUtil::UseCollisionShader(const CColor& TintColor /*= CColor::skWhite*/)
|
||||
void CDrawUtil::UseCollisionShader(bool IsFloor, bool IsUnstandable, const CColor& TintColor /*= CColor::skWhite*/)
|
||||
{
|
||||
Init();
|
||||
mpCollisionShader->SetCurrent();
|
||||
LoadCheckerboardTexture(0);
|
||||
|
||||
// Force blend mode to opaque + set alpha to 0 to ensure collision geometry isn't bloomed
|
||||
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ZERO, GL_ZERO);
|
||||
|
||||
static GLuint TintColorLoc = mpCollisionShader->GetUniformLocation("TintColor");
|
||||
glUniform4f(TintColorLoc, TintColor.R, TintColor.G, TintColor.B, TintColor.A);
|
||||
|
||||
static GLuint IsFloorLoc = mpCollisionShader->GetUniformLocation("IsFloor");
|
||||
glUniform1i(IsFloorLoc, IsFloor ? 1 : 0);
|
||||
|
||||
static GLuint IsUnstandableLoc = mpCollisionShader->GetUniformLocation("IsUnstandable");
|
||||
glUniform1i(IsUnstandableLoc, IsUnstandable ? 1 : 0);
|
||||
|
||||
CMaterial::KillCachedMaterial();
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
static void UseColorShaderLighting(const CColor& Color);
|
||||
static void UseTextureShader();
|
||||
static void UseTextureShader(const CColor& TintColor);
|
||||
static void UseCollisionShader(const CColor& TintColor = CColor::skWhite);
|
||||
static void UseCollisionShader(bool IsFloor, bool IsUnstandable, const CColor& TintColor = CColor::skWhite);
|
||||
|
||||
static CShader* GetTextShader();
|
||||
static void LoadCheckerboardTexture(u32 GLTextureUnit);
|
||||
|
||||
@@ -1,11 +1,34 @@
|
||||
#ifndef SVIEWINFO
|
||||
#define SVIEWINFO
|
||||
|
||||
#include "Core/Resource/CCollisionMaterial.h"
|
||||
#include "Core/Scene/FShowFlags.h"
|
||||
#include <Math/CFrustumPlanes.h>
|
||||
#include <Math/CMatrix4f.h>
|
||||
#include <Math/CRay.h>
|
||||
|
||||
struct SCollisionRenderSettings
|
||||
{
|
||||
u64 HighlightMask;
|
||||
u64 HideMask;
|
||||
|
||||
CCollisionMaterial HideMaterial;
|
||||
bool DrawWireframe;
|
||||
bool DrawBackfaces;
|
||||
bool DrawAreaCollisionBounds;
|
||||
bool TintWithSurfaceColor;
|
||||
bool TintUnwalkableTris;
|
||||
|
||||
SCollisionRenderSettings()
|
||||
: HighlightMask(0)
|
||||
, HideMask(0)
|
||||
, DrawWireframe(true)
|
||||
, DrawBackfaces(false)
|
||||
, DrawAreaCollisionBounds(true)
|
||||
, TintWithSurfaceColor(true)
|
||||
, TintUnwalkableTris(true) {}
|
||||
};
|
||||
|
||||
struct SViewInfo
|
||||
{
|
||||
class CScene *pScene;
|
||||
@@ -14,6 +37,7 @@ struct SViewInfo
|
||||
|
||||
bool GameMode;
|
||||
FShowFlags ShowFlags;
|
||||
SCollisionRenderSettings CollisionSettings;
|
||||
CFrustumPlanes ViewFrustum;
|
||||
CMatrix4f RotationOnlyViewMatrix;
|
||||
};
|
||||
|
||||
83
src/Core/Resource/CCollisionMaterial.cpp
Normal file
83
src/Core/Resource/CCollisionMaterial.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "CCollisionMaterial.h"
|
||||
#include <Common/AssertMacro.h>
|
||||
#include <unordered_map>
|
||||
|
||||
ECollisionFlag CCollisionMaterial::SurfaceType(EGame Game) const
|
||||
{
|
||||
// Arrays determining the type hierarchy for each game.
|
||||
// Flags earlier in the list take priority over flags later in the list.
|
||||
static const ECollisionFlag skPrimeTypeHierarchy[] = {
|
||||
eCF_Organic, eCF_Wood, eCF_Sand, eCF_Shield, eCF_Glass, eCF_Mud, eCF_SlowMud,
|
||||
eCF_Snow, eCF_Lava, eCF_Dirt, eCF_Phazon, eCF_MetalGrating, eCF_Ice, eCF_Grass,
|
||||
eCF_Metal, eCF_Stone
|
||||
};
|
||||
static const ECollisionFlag skEchoesTypeHierarchy[] = {
|
||||
eCF_Rubber, eCF_Organic, eCF_Wood, eCF_Web, eCF_MothSeedOrganics, eCF_Sand,
|
||||
eCF_Shield, eCF_Fabric, eCF_Snow, eCF_Glass, eCF_AltMetal, eCF_Dirt, eCF_Phazon,
|
||||
eCF_MetalGrating, eCF_Ice, eCF_Grass, eCF_Metal, eCF_Stone
|
||||
};
|
||||
|
||||
// Determine which list we should use.
|
||||
const ECollisionFlag* pkFlagArray;
|
||||
u32 Num;
|
||||
|
||||
if (Game <= ePrime)
|
||||
{
|
||||
pkFlagArray = skPrimeTypeHierarchy;
|
||||
Num = sizeof(skPrimeTypeHierarchy) / sizeof(ECollisionFlag);
|
||||
}
|
||||
else
|
||||
{
|
||||
pkFlagArray = skEchoesTypeHierarchy;
|
||||
Num = sizeof(skEchoesTypeHierarchy) / sizeof(ECollisionFlag);
|
||||
}
|
||||
|
||||
// Locate type.
|
||||
for (u32 iType = 0; iType < Num; iType++)
|
||||
{
|
||||
if (*this & pkFlagArray[iType])
|
||||
return pkFlagArray[iType];
|
||||
}
|
||||
return eCF_Unknown;
|
||||
}
|
||||
|
||||
// Type-to-color mappings
|
||||
const std::unordered_map<ECollisionFlag, CColor> gkTypeToColor = {
|
||||
{ eCF_Stone, CColor::Integral(220, 215, 160) }, // Brownish/greenish
|
||||
{ eCF_Metal, CColor::Integral(143, 143, 143) }, // Gray
|
||||
{ eCF_Grass, CColor::Integral( 90, 150, 70) }, // Green
|
||||
{ eCF_Ice, CColor::Integral(200, 255, 255) }, // Light blue
|
||||
{ eCF_MetalGrating, CColor::Integral(180, 180, 180) }, // Gray
|
||||
{ eCF_Phazon, CColor::Integral( 0, 128, 255) }, // Blue
|
||||
{ eCF_Dirt, CColor::Integral(107, 84, 40) }, // Brown
|
||||
{ eCF_Lava, CColor::Integral(200, 30, 30) }, // Red
|
||||
{ eCF_AltMetal, CColor::Integral(100, 100, 100) }, // Gray
|
||||
{ eCF_Snow, CColor::Integral(230, 255, 255) }, // *Very* light blue
|
||||
{ eCF_Fabric, CColor::Integral( 64, 133, 236) }, // Blue
|
||||
{ eCF_SlowMud, CColor::Integral(109, 91, 66) }, // Brown
|
||||
{ eCF_Mud, CColor::Integral(121, 106, 84) }, // Brown
|
||||
{ eCF_Glass, CColor::Integral(172, 209, 254) }, // Greenish blue
|
||||
{ eCF_Shield, CColor::Integral(230, 250, 60) }, // Yellow
|
||||
{ eCF_Sand, CColor::Integral(225, 188, 133) }, // Light brown
|
||||
{ eCF_MothSeedOrganics, CColor::Integral(172, 170, 202) }, // Light purple
|
||||
{ eCF_Web, CColor::Integral(191, 176, 162) }, // Light grayish/brown
|
||||
{ eCF_Wood, CColor::Integral(139, 90, 43) }, // Brown
|
||||
{ eCF_Organic, CColor::Integral(130, 130, 250) }, // Purple
|
||||
{ eCF_Rubber, CColor::Integral( 58, 58, 58) } // Black
|
||||
};
|
||||
CColor CCollisionMaterial::SurfaceColor(EGame Game) const
|
||||
{
|
||||
ECollisionFlag SurfType = SurfaceType(Game);
|
||||
auto FindColor = gkTypeToColor.find(SurfType);
|
||||
return (FindColor == gkTypeToColor.end() ? CColor::skWhite : FindColor->second);
|
||||
}
|
||||
|
||||
bool CCollisionMaterial::IsFloor() const
|
||||
{
|
||||
return HasFlag(eCF_Floor) && !HasFlag(eCF_JumpNotAllowed);
|
||||
}
|
||||
|
||||
bool CCollisionMaterial::IsUnstandable(EGame Game) const
|
||||
{
|
||||
return HasFlag(eCF_JumpNotAllowed) || (Game >= eEchoesDemo && !HasFlag(eCF_Floor) && HasAnyFlags(eCF_Wall | eCF_Ceiling));
|
||||
}
|
||||
66
src/Core/Resource/CCollisionMaterial.h
Normal file
66
src/Core/Resource/CCollisionMaterial.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifndef CCOLLISIONMATERIAL
|
||||
#define CCOLLISIONMATERIAL
|
||||
|
||||
#include <Common/CColor.h>
|
||||
#include <Common/EGame.h>
|
||||
#include <Common/Flags.h>
|
||||
|
||||
// Game-neutral collision property flags.
|
||||
// IMPORTANT: This is an incomplete list. Keep in mind that MP2, MP3, and DKCR store
|
||||
// collision materials via a 64-bit flag where every bit is used, and some flags differ
|
||||
// between games. Therefore a single enum doesn't have the resolution to represent EVERY
|
||||
// flag from EVERY game. In the future, the storage medium needs to be changed to a struct,
|
||||
// OR we need to be okay with excluding certain flags (which we probably are, because a
|
||||
// lot of them aren't meant to be used by collision geometry, such as the "Player" flag).
|
||||
enum ECollisionFlag
|
||||
{
|
||||
eCF_Unknown = 0x00000001,
|
||||
eCF_Stone = 0x00000002,
|
||||
eCF_Metal = 0x00000004,
|
||||
eCF_Grass = 0x00000008,
|
||||
eCF_Ice = 0x00000010,
|
||||
eCF_MetalGrating = 0x00000020,
|
||||
eCF_Phazon = 0x00000040,
|
||||
eCF_Dirt = 0x00000080,
|
||||
eCF_Lava = 0x00000100,
|
||||
eCF_AltMetal = 0x00000200,
|
||||
eCF_Snow = 0x00000400,
|
||||
eCF_Fabric = 0x00000800,
|
||||
eCF_SlowMud = 0x00001000,
|
||||
eCF_Mud = 0x00002000,
|
||||
eCF_Glass = 0x00004000,
|
||||
eCF_Shield = 0x00008000,
|
||||
eCF_Sand = 0x00010000,
|
||||
eCF_MothSeedOrganics = 0x00020000,
|
||||
eCF_Web = 0x00040000,
|
||||
eCF_Wood = 0x00080000,
|
||||
eCF_Organic = 0x00100000,
|
||||
eCF_Rubber = 0x00200000,
|
||||
eCF_ShootThru = 0x00400000,
|
||||
eCF_CameraThru = 0x00800000,
|
||||
eCF_ScanThru = 0x01000000,
|
||||
eCF_AiWalkThru = 0x02000000,
|
||||
eCF_FlippedTri = 0x04000000,
|
||||
eCF_Ceiling = 0x08000000,
|
||||
eCF_Wall = 0x10000000,
|
||||
eCF_Floor = 0x20000000,
|
||||
eCF_AiBlock = 0x40000000,
|
||||
eCF_JumpNotAllowed = 0x80000000
|
||||
};
|
||||
|
||||
class CCollisionMaterial : public TFlags<ECollisionFlag>
|
||||
{
|
||||
friend class CCollisionLoader;
|
||||
u64 mRawFlags;
|
||||
|
||||
public:
|
||||
ECollisionFlag SurfaceType(EGame Game) const;
|
||||
CColor SurfaceColor(EGame Game) const;
|
||||
bool IsFloor() const;
|
||||
bool IsUnstandable(EGame Game) const;
|
||||
|
||||
inline u64 RawFlags() const { return mRawFlags; }
|
||||
};
|
||||
|
||||
#endif // CCOLLISIONMATERIAL
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#include "CCollisionMesh.h"
|
||||
#include "Core/Render/CRenderer.h"
|
||||
#include "Core/Render/CDrawUtil.h"
|
||||
#include <Common/AssertMacro.h>
|
||||
|
||||
CCollisionMesh::CCollisionMesh()
|
||||
{
|
||||
mVBO.SetVertexDesc(ePosition);
|
||||
mVBO.SetVertexDesc(ePosition | eNormal);
|
||||
mVertexCount = 0;
|
||||
mLineCount = 0;
|
||||
mFaceCount = 0;
|
||||
@@ -31,23 +32,39 @@ void CCollisionMesh::BufferGL()
|
||||
mBuffered = false;
|
||||
}
|
||||
|
||||
// Add all the verts to our VBO, first...
|
||||
mVBO.Reserve(mCollisionVertices.size());
|
||||
for (u16 iVtx = 0; iVtx < mCollisionVertices.size(); iVtx++)
|
||||
mVBO.AddVertex(CVertex(mCollisionVertices[iVtx].Pos));
|
||||
// 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;
|
||||
});
|
||||
|
||||
// Then add all the relevant indices to the IBO
|
||||
mIBO.Reserve(mCollisionFaces.size() * 3);
|
||||
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]))
|
||||
@@ -56,17 +73,40 @@ void CCollisionMesh::BufferGL()
|
||||
Verts[2] = pLineB->Vertices[1];
|
||||
|
||||
// Some faces have a property that indicates they need to be inverted
|
||||
if (!pFace->Properties.Invert)
|
||||
mIBO.AddIndices(&Verts[0], 3);
|
||||
|
||||
else
|
||||
if (GetMaterial(pFace->MaterialIdx) & eCF_FlippedTri)
|
||||
{
|
||||
mIBO.AddIndex(Verts[2]);
|
||||
mIBO.AddIndex(Verts[1]);
|
||||
mIBO.AddIndex(Verts[0]);
|
||||
u16 V0 = Verts[0];
|
||||
Verts[0] = Verts[2];
|
||||
Verts[2] = V0;
|
||||
}
|
||||
|
||||
// Generate vertices - we don't share vertices between triangles in order to get the generated normals looking correct
|
||||
CCollisionVertex& rVert0 = mCollisionVertices[Verts[0]];
|
||||
CCollisionVertex& rVert1 = mCollisionVertices[Verts[1]];
|
||||
CCollisionVertex& rVert2 = mCollisionVertices[Verts[2]];
|
||||
|
||||
CVector3f V0toV1 = (rVert1.Pos - rVert0.Pos).Normalized();
|
||||
CVector3f V0toV2 = (rVert2.Pos - rVert0.Pos).Normalized();
|
||||
CVector3f FaceNormal = V0toV1.Cross(V0toV2).Normalized();
|
||||
|
||||
for (u32 iVtx = 0; iVtx < 3; iVtx++)
|
||||
{
|
||||
CVertex Vtx;
|
||||
Vtx.Position = mCollisionVertices[ Verts[iVtx] ].Pos;
|
||||
Vtx.Normal = FaceNormal;
|
||||
u16 Index = mVBO.AddVertex(Vtx);
|
||||
mIBO.AddIndex(Index);
|
||||
}
|
||||
}
|
||||
|
||||
while (CurMat != mMaterials.size())
|
||||
{
|
||||
mMaterialOffsets.push_back(mIBO.GetSize());
|
||||
CurMat++;
|
||||
}
|
||||
|
||||
ASSERT(mMaterialOffsets.size() == mMaterials.size());
|
||||
|
||||
// Buffer, and done
|
||||
mVBO.Buffer();
|
||||
mIBO.Buffer();
|
||||
@@ -82,6 +122,29 @@ void CCollisionMesh::Draw()
|
||||
mVBO.Unbind();
|
||||
}
|
||||
|
||||
void CCollisionMesh::DrawMaterial(u32 MatIdx, bool Wireframe)
|
||||
{
|
||||
if (!mBuffered) BufferGL();
|
||||
ASSERT(MatIdx < mMaterials.size());
|
||||
|
||||
mVBO.Bind();
|
||||
u32 StartIdx = (MatIdx == 0 ? 0 : mMaterialOffsets[MatIdx - 1]);
|
||||
u32 NumElements = mMaterialOffsets[MatIdx] - StartIdx;
|
||||
|
||||
if (Wireframe)
|
||||
{
|
||||
CDrawUtil::UseColorShader(CColor::skBlack);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
}
|
||||
|
||||
mIBO.DrawElements(StartIdx, NumElements);
|
||||
|
||||
if (Wireframe)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
mVBO.Unbind();
|
||||
}
|
||||
|
||||
void CCollisionMesh::DrawWireframe()
|
||||
{
|
||||
CDrawUtil::UseColorShader(CColor::skBlack);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef CCOLLISIONMESH_H
|
||||
#define CCOLLISIONMESH_H
|
||||
|
||||
#include "CCollisionMaterial.h"
|
||||
#include "CResource.h"
|
||||
#include "Core/OpenGL/CVertexBuffer.h"
|
||||
#include "Core/OpenGL/CIndexBuffer.h"
|
||||
@@ -30,30 +31,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 +61,11 @@ class CCollisionMesh
|
||||
|
||||
CAABox mAABox;
|
||||
CCollisionOctree *mpOctree;
|
||||
std::vector<u32> mFlags;
|
||||
std::vector<CCollisionMaterial> 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 +78,12 @@ public:
|
||||
|
||||
void BufferGL();
|
||||
void Draw();
|
||||
void DrawMaterial(u32 MatIdx, bool Wireframe);
|
||||
void DrawWireframe();
|
||||
|
||||
inline u32 NumMaterials() const { return mMaterials.size(); }
|
||||
inline CCollisionMaterial& GetMaterial(u32 Index) { return mMaterials[Index]; }
|
||||
inline const CAABox& BoundingBox() const { return mAABox; }
|
||||
};
|
||||
|
||||
#endif // CCOLLISIONMESH_H
|
||||
|
||||
@@ -38,27 +38,79 @@ void CCollisionLoader::ParseOBBNode(IInputStream& rDCLN)
|
||||
|
||||
void CCollisionLoader::ReadPropertyFlags(IInputStream& rSrc)
|
||||
{
|
||||
CCollisionMesh::SCollisionProperties Property;
|
||||
CCollisionMaterial Material;
|
||||
u64 RawFlags = (mVersion <= ePrime ? rSrc.ReadLong() : rSrc.ReadLongLong());
|
||||
Material.mRawFlags = RawFlags;
|
||||
|
||||
if (mVersion == ePrime)
|
||||
if (mVersion <= ePrime)
|
||||
{
|
||||
u32 Flag = rSrc.ReadLong();
|
||||
Property.Invert = (Flag >> 25) & 0x1;
|
||||
if (RawFlags & 0x00000001) Material |= eCF_Unknown;
|
||||
if (RawFlags & 0x00000002) Material |= eCF_Stone;
|
||||
if (RawFlags & 0x00000004) Material |= eCF_Metal;
|
||||
if (RawFlags & 0x00000008) Material |= eCF_Grass;
|
||||
if (RawFlags & 0x00000010) Material |= eCF_Ice;
|
||||
if (RawFlags & 0x00000040) Material |= eCF_MetalGrating;
|
||||
if (RawFlags & 0x00000080) Material |= eCF_Phazon;
|
||||
if (RawFlags & 0x00000100) Material |= eCF_Dirt;
|
||||
if (RawFlags & 0x00000200) Material |= eCF_Lava;
|
||||
if (RawFlags & 0x00000800) Material |= eCF_Snow;
|
||||
if (RawFlags & 0x00001000) Material |= eCF_SlowMud;
|
||||
if (RawFlags & 0x00004000) Material |= eCF_Mud;
|
||||
if (RawFlags & 0x00008000) Material |= eCF_Glass;
|
||||
if (RawFlags & 0x00010000) Material |= eCF_Shield;
|
||||
if (RawFlags & 0x00020000) Material |= eCF_Sand;
|
||||
if (RawFlags & 0x00040000) Material |= eCF_ShootThru;
|
||||
if (RawFlags & 0x00200000) Material |= eCF_CameraThru;
|
||||
if (RawFlags & 0x00400000) Material |= eCF_Wood;
|
||||
if (RawFlags & 0x00800000) Material |= eCF_Organic;
|
||||
if (RawFlags & 0x02000000) Material |= eCF_FlippedTri;
|
||||
if (RawFlags & 0x08000000) Material |= eCF_ScanThru;
|
||||
if (RawFlags & 0x10000000) Material |= eCF_AiWalkThru;
|
||||
if (RawFlags & 0x20000000) Material |= eCF_Ceiling;
|
||||
if (RawFlags & 0x40000000) Material |= eCF_Wall;
|
||||
if (RawFlags & 0x80000000) Material |= eCF_Floor;
|
||||
}
|
||||
|
||||
else if (mVersion == eEchoes)
|
||||
else if (mVersion <= eCorruption)
|
||||
{
|
||||
u64 Flag = rSrc.ReadLongLong();
|
||||
Property.Invert = (Flag >> 24) & 0x1;
|
||||
if (RawFlags & 0x00000001) Material |= eCF_Unknown;
|
||||
if (RawFlags & 0x00000002) Material |= eCF_Stone;
|
||||
if (RawFlags & 0x00000004) Material |= eCF_Metal;
|
||||
if (RawFlags & 0x00000008) Material |= eCF_Grass;
|
||||
if (RawFlags & 0x00000010) Material |= eCF_Ice;
|
||||
if (RawFlags & 0x00000040) Material |= eCF_MetalGrating;
|
||||
if (RawFlags & 0x00000080) Material |= eCF_Phazon;
|
||||
if (RawFlags & 0x00000100) Material |= eCF_Dirt;
|
||||
if (RawFlags & 0x00000200) Material |= eCF_AltMetal;
|
||||
if (RawFlags & 0x00000400) Material |= eCF_Glass;
|
||||
if (RawFlags & 0x00000800) Material |= eCF_Snow;
|
||||
if (RawFlags & 0x00001000) Material |= eCF_Fabric;
|
||||
if (RawFlags & 0x00010000) Material |= eCF_Shield;
|
||||
if (RawFlags & 0x00020000) Material |= eCF_Sand;
|
||||
if (RawFlags & 0x00040000) Material |= eCF_MothSeedOrganics;
|
||||
if (RawFlags & 0x00080000) Material |= eCF_Web;
|
||||
if (RawFlags & 0x00100000) Material |= eCF_ShootThru;
|
||||
if (RawFlags & 0x00200000) Material |= eCF_CameraThru;
|
||||
if (RawFlags & 0x00400000) Material |= eCF_Wood;
|
||||
if (RawFlags & 0x00800000) Material |= eCF_Organic;
|
||||
if (RawFlags & 0x01000000) Material |= eCF_FlippedTri;
|
||||
if (RawFlags & 0x02000000) Material |= eCF_Rubber;
|
||||
if (RawFlags & 0x08000000) Material |= eCF_ScanThru;
|
||||
if (RawFlags & 0x10000000) Material |= eCF_AiWalkThru;
|
||||
if (RawFlags & 0x20000000) Material |= eCF_Ceiling;
|
||||
if (RawFlags & 0x40000000) Material |= eCF_Wall;
|
||||
if (RawFlags & 0x80000000) Material |= eCF_Floor;
|
||||
|
||||
if (RawFlags & 0x0001000000000000) Material |= eCF_AiBlock;
|
||||
if (RawFlags & 0x0400000000000000) Material |= eCF_JumpNotAllowed;
|
||||
}
|
||||
|
||||
else if (mVersion == eReturns)
|
||||
{
|
||||
u64 Flag = rSrc.ReadLongLong();
|
||||
Property.Invert = (Flag >> 28) & 0x1;
|
||||
if (RawFlags & 0x10000000) Material |= eCF_FlippedTri;
|
||||
}
|
||||
|
||||
mProperties.push_back(Property);
|
||||
mpMesh->mMaterials.push_back(Material);
|
||||
}
|
||||
|
||||
void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox)
|
||||
@@ -89,7 +141,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 +154,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 +173,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;
|
||||
|
||||
@@ -10,7 +10,6 @@ class CCollisionLoader
|
||||
TResPtr<CCollisionMeshGroup> mpGroup;
|
||||
CCollisionMesh *mpMesh;
|
||||
EGame mVersion;
|
||||
std::vector<CCollisionMesh::SCollisionProperties> mProperties;
|
||||
|
||||
CCollisionLoader();
|
||||
CCollisionMesh::CCollisionOctree* ParseOctree(IInputStream& rSrc);
|
||||
|
||||
@@ -160,6 +160,7 @@ CResource* CScriptTemplate::FindDisplayAsset(CPropertyStruct *pProperties, u32&
|
||||
|
||||
for (auto it = mAssets.begin(); it != mAssets.end(); it++)
|
||||
{
|
||||
if (it->AssetType == SEditorAsset::eCollision) continue;
|
||||
CResource *pRes = nullptr;
|
||||
|
||||
// File
|
||||
|
||||
@@ -37,10 +37,56 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
CDrawUtil::UseCollisionShader(TintColor(rkViewInfo));
|
||||
mpCollision->Draw();
|
||||
CDrawUtil::UseColorShader(CColor::skTransparentBlack);
|
||||
mpCollision->DrawWireframe();
|
||||
// Turn off backface culling
|
||||
EGame CollisionGame = mpCollision->Game();
|
||||
bool ForceDisableBackfaceCull = (rkViewInfo.CollisionSettings.DrawBackfaces || CollisionGame == eReturns) && glIsEnabled(GL_CULL_FACE);
|
||||
|
||||
if (ForceDisableBackfaceCull)
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
CColor BaseTint = TintColor(rkViewInfo);
|
||||
|
||||
for (u32 iMesh = 0; iMesh < mpCollision->NumMeshes(); iMesh++)
|
||||
{
|
||||
CCollisionMesh *pMesh = mpCollision->MeshByIndex(iMesh);
|
||||
|
||||
for (u32 iMat = 0; iMat < pMesh->NumMaterials(); iMat++)
|
||||
{
|
||||
CCollisionMaterial& rMat = pMesh->GetMaterial(iMat);
|
||||
|
||||
if (rkViewInfo.CollisionSettings.HideMaterial & rMat)
|
||||
continue;
|
||||
|
||||
if (rkViewInfo.CollisionSettings.HideMask != 0 && (rMat.RawFlags() & rkViewInfo.CollisionSettings.HideMask) != 0)
|
||||
continue;
|
||||
|
||||
CColor Tint = BaseTint;
|
||||
|
||||
if (rkViewInfo.CollisionSettings.HighlightMask != 0 && (rMat.RawFlags() & rkViewInfo.CollisionSettings.HighlightMask) == rkViewInfo.CollisionSettings.HighlightMask)
|
||||
Tint *= CColor::skRed;
|
||||
|
||||
else if (CollisionGame != eReturns && rkViewInfo.CollisionSettings.TintWithSurfaceColor)
|
||||
Tint *= rMat.SurfaceColor(CollisionGame);
|
||||
|
||||
bool IsFloor = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.IsFloor() : true) || CollisionGame == eReturns;
|
||||
bool IsUnstandable = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.IsUnstandable(CollisionGame) : false) && CollisionGame != eReturns;
|
||||
CDrawUtil::UseCollisionShader(IsFloor, IsUnstandable, Tint);
|
||||
pMesh->DrawMaterial(iMat, false);
|
||||
|
||||
if (rkViewInfo.CollisionSettings.DrawWireframe)
|
||||
pMesh->DrawMaterial(iMat, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Restore backface culling setting
|
||||
if (ForceDisableBackfaceCull)
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
// Draw collision bounds for area collision
|
||||
// note: right now checking parent is the best way to check whether this node is area collision instead of actor collision
|
||||
// actor collision will have a script node parent whereas area collision will have a root node parent
|
||||
if (rkViewInfo.CollisionSettings.DrawAreaCollisionBounds && Parent()->NodeType() == eRootNode && CollisionGame != eReturns)
|
||||
CDrawUtil::DrawWireCube( mpCollision->MeshByIndex(0)->BoundingBox(), CColor::skRed );
|
||||
}
|
||||
|
||||
void CCollisionNode::RayAABoxIntersectTest(CRayCollisionTester& /*rTester*/, const SViewInfo& /*rkViewInfo*/)
|
||||
|
||||
Reference in New Issue
Block a user