From da5676d25bec3429817c51df20cd39e7e71eeb20 Mon Sep 17 00:00:00 2001 From: parax0 Date: Tue, 3 May 2016 14:26:14 -0600 Subject: [PATCH 01/10] Enable public release mode for release branch --- src/.qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/.qmake.conf b/src/.qmake.conf index 873372a5..1be9b87b 100644 --- a/src/.qmake.conf +++ b/src/.qmake.conf @@ -1,4 +1,4 @@ -# CONFIG += PUBLIC_RELEASE +CONFIG += PUBLIC_RELEASE DEFINES += 'APP_NAME=\"\\\"Prime World Editor\\\"\"' \ 'APP_VERSION=\"\\\"1.1.0\\\"\"' From c0fb54888ddcf97f45f8672b65e104b7e2ecc634 Mon Sep 17 00:00:00 2001 From: parax0 Date: Sat, 24 Dec 2016 03:05:51 -0700 Subject: [PATCH 02/10] Rewrote collision shader to use generated normals with fake lighting instead of generated UV coords --- resources/shaders/CollisionShader.ps | 5 ++-- resources/shaders/CollisionShader.vs | 19 ++++++------- src/Core/Render/CDrawUtil.cpp | 1 - src/Core/Resource/CCollisionMesh.cpp | 40 ++++++++++++++++++---------- src/Core/Scene/CCollisionNode.cpp | 2 -- 5 files changed, 38 insertions(+), 29 deletions(-) diff --git a/resources/shaders/CollisionShader.ps b/resources/shaders/CollisionShader.ps index fafa23e6..84413ce5 100644 --- a/resources/shaders/CollisionShader.ps +++ b/resources/shaders/CollisionShader.ps @@ -1,17 +1,16 @@ #version 330 core // Input -in vec2 TexCoord; +in vec4 LightColor; // Output out vec4 PixelColor; // Uniforms -uniform sampler2D Texture; uniform vec4 TintColor; // Main void main() { - PixelColor = vec4(texture(Texture, TexCoord).rgb, 0) * TintColor; + PixelColor = LightColor * TintColor; } diff --git a/resources/shaders/CollisionShader.vs b/resources/shaders/CollisionShader.vs index cbb5419c..1926ae0f 100644 --- a/resources/shaders/CollisionShader.vs +++ b/resources/shaders/CollisionShader.vs @@ -1,11 +1,11 @@ -// This shader will be obsoleted soon when the collision rendering is improved #version 330 core // Input -layout(location = 0) in vec3 Position; +layout(location = 0) in vec3 RawPosition; +layout(location = 1) in vec3 RawNormal; // Output -out vec2 TexCoord; +out vec4 LightColor; // Uniforms layout(std140) uniform MVPBlock @@ -18,11 +18,12 @@ layout(std140) uniform MVPBlock // Main void main() { - mat4 MVP = ModelMtx * ViewMtx * ProjMtx; - gl_Position = vec4(Position, 1) * MVP; + mat4 MVP = ModelMtx * ViewMtx * ProjMtx; + gl_Position = vec4(RawPosition, 1) * MVP; - // UV Generation - float avg = (Position.x + Position.z) / 2; - TexCoord.x = avg; - TexCoord.y = Position.y + (avg / 2); + // Fake lighting; render one white skylight pointing straight down with an ambient 0.5 + float LightDot = dot(RawNormal, vec3(0, 0, -1)); + float Alpha = (-LightDot + 1.0) / 2; + float LightAlpha = mix(0.5, 0.9, Alpha); + LightColor = vec4(LightAlpha, LightAlpha, LightAlpha, 1.0); } diff --git a/src/Core/Render/CDrawUtil.cpp b/src/Core/Render/CDrawUtil.cpp index 654d9409..0a7e1e5e 100644 --- a/src/Core/Render/CDrawUtil.cpp +++ b/src/Core/Render/CDrawUtil.cpp @@ -333,7 +333,6 @@ void CDrawUtil::UseCollisionShader(const CColor& TintColor /*= CColor::skWhite*/ { Init(); mpCollisionShader->SetCurrent(); - LoadCheckerboardTexture(0); static GLuint TintColorLoc = mpCollisionShader->GetUniformLocation("TintColor"); glUniform4f(TintColorLoc, TintColor.R, TintColor.G, TintColor.B, TintColor.A); diff --git a/src/Core/Resource/CCollisionMesh.cpp b/src/Core/Resource/CCollisionMesh.cpp index ee8f9187..d1b5bbb9 100644 --- a/src/Core/Resource/CCollisionMesh.cpp +++ b/src/Core/Resource/CCollisionMesh.cpp @@ -4,7 +4,7 @@ CCollisionMesh::CCollisionMesh() { - mVBO.SetVertexDesc(ePosition); + mVBO.SetVertexDesc(ePosition | eNormal); mVertexCount = 0; mLineCount = 0; mFaceCount = 0; @@ -31,13 +31,10 @@ 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)); - - // Then add all the relevant indices to the IBO + // Add all the relevant indices to the IBO + mVBO.Reserve(mCollisionFaces.size() * 3); mIBO.Reserve(mCollisionFaces.size() * 3); + for (u32 iVtx = 0; iVtx < mCollisionFaces.size(); iVtx++) { u16 Verts[3]; @@ -56,14 +53,29 @@ 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 (pFace->Properties.Invert) { - 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); } } diff --git a/src/Core/Scene/CCollisionNode.cpp b/src/Core/Scene/CCollisionNode.cpp index 6af38244..06080c20 100644 --- a/src/Core/Scene/CCollisionNode.cpp +++ b/src/Core/Scene/CCollisionNode.cpp @@ -39,8 +39,6 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER CDrawUtil::UseCollisionShader(TintColor(rkViewInfo)); mpCollision->Draw(); - CDrawUtil::UseColorShader(CColor::skTransparentBlack); - mpCollision->DrawWireframe(); } SRayIntersection CCollisionNode::RayNodeIntersectTest(const CRay& /*rkRay*/, u32 /*AssetID*/, const SViewInfo& /*rkViewInfo*/) From 78baa42bcee1b4e8d25931fa9cce05ecb2db3d98 Mon Sep 17 00:00:00 2001 From: parax0 Date: Sun, 25 Dec 2016 14:47:59 -0700 Subject: [PATCH 03/10] Added fog to the collision shader, made changes to enable rendering different collision materials separately (also, murry crimmas) --- resources/shaders/CollisionShader.ps | 19 ++++++- resources/shaders/CollisionShader.vs | 11 ++-- src/Core/Resource/CCollisionMesh.cpp | 52 ++++++++++++++++--- src/Core/Resource/CCollisionMesh.h | 30 +++++++---- .../Resource/Factory/CCollisionLoader.cpp | 22 ++++---- src/Core/Resource/Factory/CCollisionLoader.h | 1 - src/Core/Scene/CCollisionNode.cpp | 17 +++++- 7 files changed, 118 insertions(+), 34 deletions(-) diff --git a/resources/shaders/CollisionShader.ps b/resources/shaders/CollisionShader.ps index 84413ce5..138164de 100644 --- a/resources/shaders/CollisionShader.ps +++ b/resources/shaders/CollisionShader.ps @@ -9,8 +9,25 @@ out vec4 PixelColor; // Uniforms uniform vec4 TintColor; +// Functions +float InterpolateDecelerate(float Min, float Max, float t, float Factor) +{ + float Alpha = (1.0 - pow(1.0 - t, Factor)); + return mix(Min, Max, Alpha); +} + // Main void main() { - PixelColor = LightColor * TintColor; + const float kMaxDepth = 75.0; // Controls the max depth range that kDepthTintNear and kDepthTintFar are interpolated between + const float kDepthTintNear = 0.0; // Sets the pixel color offset for pixels close to the screen + const float kDepthTintFar = -0.2; // Sets the pixel color offset for pixels far from the screen + const float kDepthCurveFactor = 2; // Controls the strength of the interpolation curve (higher = color chabges faster from up close and slower from further away) + + // Apply some fake fog so pixels closer to the camera appear slightly brighter + float Depth = ( (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) / (gl_DepthRange.far - gl_DepthRange.near) ) / gl_FragCoord.w; + float DepthAlpha = min(Depth, kMaxDepth) / kMaxDepth; + DepthAlpha = clamp(DepthAlpha, 0.0, 1.0); + float DepthTint = InterpolateDecelerate(kDepthTintNear, kDepthTintFar, DepthAlpha, kDepthCurveFactor); + PixelColor = (LightColor + vec4(DepthTint, DepthTint, DepthTint, 1.0)) * TintColor; } diff --git a/resources/shaders/CollisionShader.vs b/resources/shaders/CollisionShader.vs index 1926ae0f..88a16699 100644 --- a/resources/shaders/CollisionShader.vs +++ b/resources/shaders/CollisionShader.vs @@ -18,12 +18,17 @@ layout(std140) uniform MVPBlock // Main void main() { + const vec3 kLightDir = normalize( vec3(0.3, 0, -1) ); // Sets the direction of the light + const float kLightColorMin = 0.5; // Sets the minimum light color (color of a vertex facing away from the light) + const float kLightColorMax = 0.9; // Sets the maximum light color (color of a vertex facing towards the light) + + // Calculate vertex position mat4 MVP = ModelMtx * ViewMtx * ProjMtx; gl_Position = vec4(RawPosition, 1) * MVP; - // Fake lighting; render one white skylight pointing straight down with an ambient 0.5 - float LightDot = dot(RawNormal, vec3(0, 0, -1)); + // Apply some simple lighting + float LightDot = dot(RawNormal, kLightDir); float Alpha = (-LightDot + 1.0) / 2; - float LightAlpha = mix(0.5, 0.9, Alpha); + float LightAlpha = mix(kLightColorMin, kLightColorMax, Alpha); LightColor = vec4(LightAlpha, LightAlpha, LightAlpha, 1.0); } diff --git a/src/Core/Resource/CCollisionMesh.cpp b/src/Core/Resource/CCollisionMesh.cpp index d1b5bbb9..a4cb86d9 100644 --- a/src/Core/Resource/CCollisionMesh.cpp +++ b/src/Core/Resource/CCollisionMesh.cpp @@ -1,6 +1,7 @@ #include "CCollisionMesh.h" #include "Core/Render/CRenderer.h" #include "Core/Render/CDrawUtil.h" +#include 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 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); diff --git a/src/Core/Resource/CCollisionMesh.h b/src/Core/Resource/CCollisionMesh.h index e29710e2..051cf6ef 100644 --- a/src/Core/Resource/CCollisionMesh.h +++ b/src/Core/Resource/CCollisionMesh.h @@ -6,6 +6,17 @@ #include "Core/OpenGL/CIndexBuffer.h" #include +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 mFlags; + std::vector mMaterials; std::vector mCollisionVertices; std::vector mCollisionLines; std::vector mCollisionFaces; + std::vector 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 diff --git a/src/Core/Resource/Factory/CCollisionLoader.cpp b/src/Core/Resource/Factory/CCollisionLoader.cpp index 2ad885de..bf5c4768 100644 --- a/src/Core/Resource/Factory/CCollisionLoader.cpp +++ b/src/Core/Resource/Factory/CCollisionLoader.cpp @@ -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; diff --git a/src/Core/Resource/Factory/CCollisionLoader.h b/src/Core/Resource/Factory/CCollisionLoader.h index 34787ab0..7ea6628c 100644 --- a/src/Core/Resource/Factory/CCollisionLoader.h +++ b/src/Core/Resource/Factory/CCollisionLoader.h @@ -10,7 +10,6 @@ class CCollisionLoader TResPtr mpGroup; CCollisionMesh *mpMesh; EGame mVersion; - std::vector mProperties; CCollisionLoader(); CCollisionMesh::CCollisionOctree* ParseOctree(IInputStream& rSrc); diff --git a/src/Core/Scene/CCollisionNode.cpp b/src/Core/Scene/CCollisionNode.cpp index 06080c20..937a9064 100644 --- a/src/Core/Scene/CCollisionNode.cpp +++ b/src/Core/Scene/CCollisionNode.cpp @@ -37,8 +37,21 @@ 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(); + 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++) + { + CDrawUtil::UseCollisionShader(BaseTint); + pMesh->DrawMaterial(iMat); + } + } + + //CDrawUtil::UseColorShader(CColor::skTransparentBlack); + //mpCollision->DrawWireframe(); } SRayIntersection CCollisionNode::RayNodeIntersectTest(const CRay& /*rkRay*/, u32 /*AssetID*/, const SViewInfo& /*rkViewInfo*/) From be40dfdf024b82439efd775ebfb2e0ba4d3552c3 Mon Sep 17 00:00:00 2001 From: parax0 Date: Mon, 26 Dec 2016 23:02:32 -0700 Subject: [PATCH 04/10] Added a basic UI to change collision render settings, added the ability to color collision based on the surface type --- src/Common/TString.h | 18 ++++- src/Core/Render/SViewInfo.h | 18 +++++ src/Core/Resource/CCollisionMeshGroup.h | 5 ++ .../Resource/Factory/CCollisionLoader.cpp | 2 + src/Core/Scene/CCollisionNode.cpp | 65 ++++++++++++++++++- src/Editor/CBasicViewport.h | 1 + src/Editor/Editor.pro | 9 ++- .../CCollisionRenderSettingsDialog.cpp | 40 ++++++++++++ .../CCollisionRenderSettingsDialog.h | 29 +++++++++ .../CCollisionRenderSettingsDialog.ui | 59 +++++++++++++++++ src/Editor/WorldEditor/CWorldEditor.cpp | 7 ++ src/Editor/WorldEditor/CWorldEditor.h | 3 + src/Editor/WorldEditor/CWorldEditor.ui | 6 ++ 13 files changed, 254 insertions(+), 8 deletions(-) create mode 100644 src/Editor/WorldEditor/CCollisionRenderSettingsDialog.cpp create mode 100644 src/Editor/WorldEditor/CCollisionRenderSettingsDialog.h create mode 100644 src/Editor/WorldEditor/CCollisionRenderSettingsDialog.ui diff --git a/src/Common/TString.h b/src/Common/TString.h index 5b5aea0c..e4883f52 100644 --- a/src/Common/TString.h +++ b/src/Common/TString.h @@ -301,12 +301,22 @@ public: inline u32 ToInt32(int Base = 16) const { - return std::stoul(mInternalString, nullptr, Base); + try { + return std::stoul(mInternalString, nullptr, Base); + } + catch(...) { + return 0; + } } inline u64 ToInt64(int Base = 16) const { - return std::stoull(mInternalString, nullptr, Base); + try { + return std::stoull(mInternalString, nullptr, Base); + } + catch(...) { + return 0; + } } void ToInt128(CharType* pOut, int Base = 16) const @@ -453,6 +463,10 @@ public: if (HasPrefix) Str = Str.ChopFront(2); + // If the string is empty other than the prefix, then this is not a valid hex string + if (Str.IsEmpty()) + return false; + // If we have a variable width then assign the width value to the string size Width = Str.Size(); } diff --git a/src/Core/Render/SViewInfo.h b/src/Core/Render/SViewInfo.h index 4607b417..c7fa1499 100644 --- a/src/Core/Render/SViewInfo.h +++ b/src/Core/Render/SViewInfo.h @@ -6,6 +6,23 @@ #include #include +enum ECollisionDrawMode +{ + eCDM_Default, + eCDM_TintSurfaceType +}; + +struct SCollisionRenderSettings +{ + ECollisionDrawMode DrawMode; + u64 HighlightMask; + u64 HideMask; + bool DrawWireframe; + + SCollisionRenderSettings() + : DrawMode(eCDM_TintSurfaceType), HighlightMask(0), HideMask(0), DrawWireframe(false) {} +}; + struct SViewInfo { class CScene *pScene; @@ -14,6 +31,7 @@ struct SViewInfo bool GameMode; FShowFlags ShowFlags; + SCollisionRenderSettings CollisionSettings; CFrustumPlanes ViewFrustum; CMatrix4f RotationOnlyViewMatrix; }; diff --git a/src/Core/Resource/CCollisionMeshGroup.h b/src/Core/Resource/CCollisionMeshGroup.h index a807c615..df0e501b 100644 --- a/src/Core/Resource/CCollisionMeshGroup.h +++ b/src/Core/Resource/CCollisionMeshGroup.h @@ -3,6 +3,7 @@ #include "CResource.h" #include "CCollisionMesh.h" +#include "EGame.h" #include "TResPtr.h" #include @@ -10,6 +11,7 @@ class CCollisionMeshGroup : public CResource { DECLARE_RESOURCE_TYPE(eCollisionMeshGroup) std::vector mMeshes; + EGame mGame; public: CCollisionMeshGroup() {} @@ -20,8 +22,11 @@ public: delete *it; } + inline EGame Game() const { return mGame; } inline u32 NumMeshes() const { return mMeshes.size(); } inline CCollisionMesh* MeshByIndex(u32 Index) const { return mMeshes[Index]; } + + inline void SetGame(EGame Game) { mGame = Game; } inline void AddMesh(CCollisionMesh *pMesh) { mMeshes.push_back(pMesh); } inline void Draw() diff --git a/src/Core/Resource/Factory/CCollisionLoader.cpp b/src/Core/Resource/Factory/CCollisionLoader.cpp index bf5c4768..e88629d4 100644 --- a/src/Core/Resource/Factory/CCollisionLoader.cpp +++ b/src/Core/Resource/Factory/CCollisionLoader.cpp @@ -144,6 +144,7 @@ CCollisionMeshGroup* CCollisionLoader::LoadAreaCollision(IInputStream& rMREA) loader.mVersion = GetFormatVersion(rMREA.ReadLong()); loader.mpGroup = new CCollisionMeshGroup; + loader.mpGroup->SetGame(loader.mVersion); loader.mpMesh = new CCollisionMesh; // Octree - structure is known, but not coding this right now @@ -180,6 +181,7 @@ CCollisionMeshGroup* CCollisionLoader::LoadDCLN(IInputStream& rDCLN) } Loader.mVersion = GetFormatVersion(rDCLN.ReadLong()); + Loader.mpGroup->SetGame(Loader.mVersion); Loader.mpMesh = new CCollisionMesh; Loader.mpMesh->mOctreeLoaded = false; diff --git a/src/Core/Scene/CCollisionNode.cpp b/src/Core/Scene/CCollisionNode.cpp index 937a9064..714a2da7 100644 --- a/src/Core/Scene/CCollisionNode.cpp +++ b/src/Core/Scene/CCollisionNode.cpp @@ -45,13 +45,72 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER for (u32 iMat = 0; iMat < pMesh->NumMaterials(); iMat++) { - CDrawUtil::UseCollisionShader(BaseTint); + SCollisionMaterial& rMat = pMesh->GetMaterial(iMat); + + if (rkViewInfo.CollisionSettings.HideMask != 0 && (rMat.RawFlags & rkViewInfo.CollisionSettings.HideMask) == rkViewInfo.CollisionSettings.HideMask) + continue; + + CColor Tint = BaseTint; + + if (rkViewInfo.CollisionSettings.HighlightMask != 0 && (rMat.RawFlags & rkViewInfo.CollisionSettings.HighlightMask) == rkViewInfo.CollisionSettings.HighlightMask) + Tint *= CColor::skRed; + + else if (mpCollision->Game() <= ePrime && rkViewInfo.CollisionSettings.DrawMode == eCDM_TintSurfaceType) + { + // Organic + if (rMat.RawFlags & 0x00800000) + Tint *= CColor::Integral(130, 130, 250); // Purple + // Wood + else if (rMat.RawFlags & 0x00400000) + Tint *= CColor::Integral(190, 140, 105); // Brown + // Sand + else if (rMat.RawFlags & 0x00020000) + Tint *= CColor::Integral(230, 200, 170); // Light Brown + // Shield + else if (rMat.RawFlags & 0x00010000) + Tint *= CColor::Integral(250, 230, 60); // Yellow + // Glass + else if (rMat.RawFlags & 0x00008000) + Tint *= CColor::Integral(20, 255, 190); // Greenish/Bluish + // Snow + else if (rMat.RawFlags & 0x00000800) + Tint *= CColor::Integral(230, 255, 255); // *Very* light blue + // Lava + else if (rMat.RawFlags & 0x00000200) + Tint *= CColor::Integral(200, 30, 30); // Red + // Rock + else if (rMat.RawFlags & 0x00000100) + Tint *= CColor::Integral(150, 130, 120); // Brownish-gray + // Phazon + else if (rMat.RawFlags & 0x00000080) + Tint *= CColor::Integral(0, 128, 255); // Blue + // Metal Grating + else if (rMat.RawFlags & 0x00000040) + Tint *= CColor::Integral(170, 170, 170); // Gray + // Ice + else if (rMat.RawFlags & 0x00000010) + Tint *= CColor::Integral(200, 255, 255); // Light blue + // Grass + else if (rMat.RawFlags & 0x00000008) + Tint *= CColor::Integral(90, 150, 70); // Green + // Metal + else if (rMat.RawFlags & 0x00000004) + Tint *= CColor::Integral(110, 110, 110); // Dark gray + // Stone + else if (rMat.RawFlags & 0x00000002) + Tint *= CColor::Integral(220, 215, 160); // Brown/green ish + } + + CDrawUtil::UseCollisionShader(Tint); pMesh->DrawMaterial(iMat); } } - //CDrawUtil::UseColorShader(CColor::skTransparentBlack); - //mpCollision->DrawWireframe(); + if (rkViewInfo.CollisionSettings.DrawWireframe) + { + CDrawUtil::UseColorShader(CColor::skTransparentBlack); + mpCollision->DrawWireframe(); + } } SRayIntersection CCollisionNode::RayNodeIntersectTest(const CRay& /*rkRay*/, u32 /*AssetID*/, const SViewInfo& /*rkViewInfo*/) diff --git a/src/Editor/CBasicViewport.h b/src/Editor/CBasicViewport.h index 99a9ecad..01337254 100644 --- a/src/Editor/CBasicViewport.h +++ b/src/Editor/CBasicViewport.h @@ -64,6 +64,7 @@ public: CVector2f MouseDeviceCoordinates(); double LastRenderDuration(); + inline SCollisionRenderSettings& CollisionRenderSettings() { return mViewInfo.CollisionSettings; } public slots: void ProcessInput(); void Render(); diff --git a/src/Editor/Editor.pro b/src/Editor/Editor.pro index 14e7f083..3c7c9004 100644 --- a/src/Editor/Editor.pro +++ b/src/Editor/Editor.pro @@ -164,7 +164,8 @@ HEADERS += \ CharacterEditor/CCharacterEditorViewport.h \ CGridRenderable.h \ CharacterEditor/CSkeletonHierarchyModel.h \ - CLineRenderable.h + CLineRenderable.h \ + WorldEditor/CCollisionRenderSettingsDialog.h # Source Files SOURCES += \ @@ -224,7 +225,8 @@ SOURCES += \ CAboutDialog.cpp \ CharacterEditor/CCharacterEditor.cpp \ CharacterEditor/CCharacterEditorViewport.cpp \ - CharacterEditor/CSkeletonHierarchyModel.cpp + CharacterEditor/CSkeletonHierarchyModel.cpp \ + WorldEditor/CCollisionRenderSettingsDialog.cpp # UI Files FORMS += \ @@ -245,4 +247,5 @@ FORMS += \ WorldEditor/CSelectInstanceDialog.ui \ WorldEditor/CRepackInfoDialog.ui \ CAboutDialog.ui \ - CharacterEditor/CCharacterEditor.ui + CharacterEditor/CCharacterEditor.ui \ + WorldEditor/CCollisionRenderSettingsDialog.ui diff --git a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.cpp b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.cpp new file mode 100644 index 00000000..79f17e60 --- /dev/null +++ b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.cpp @@ -0,0 +1,40 @@ +#include "CCollisionRenderSettingsDialog.h" +#include "ui_CCollisionRenderSettingsDialog.h" +#include "CWorldEditor.h" +#include "Editor/UICommon.h" + +CCollisionRenderSettingsDialog::CCollisionRenderSettingsDialog(CWorldEditor *pEditor, QWidget *pParent /*= 0*/) + : QDialog(pParent) + , mpEditor(pEditor) + , mpUi(new Ui::CCollisionRenderSettingsDialog) +{ + mpUi->setupUi(this); + + connect(mpUi->HideMaskLineEdit, SIGNAL(textChanged(QString)), this, SLOT(OnHideMaskChanged(QString))); + connect(mpUi->HighlightMaskLineEdit, SIGNAL(textChanged(QString)), this, SLOT(OnHighlightMaskChanged(QString))); + connect(mpUi->WireframeCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnWireframeToggled(bool))); +} + +CCollisionRenderSettingsDialog::~CCollisionRenderSettingsDialog() +{ + delete mpUi; +} + +void CCollisionRenderSettingsDialog::OnHideMaskChanged(QString NewMask) +{ + TString MaskStr = TO_TSTRING(NewMask); + u64 Mask = (MaskStr.IsHexString() ? MaskStr.ToInt64(16) : 0); + mpEditor->Viewport()->CollisionRenderSettings().HideMask = Mask; +} + +void CCollisionRenderSettingsDialog::OnHighlightMaskChanged(QString NewMask) +{ + TString MaskStr = TO_TSTRING(NewMask); + u64 Mask = (MaskStr.IsHexString() ? MaskStr.ToInt64(16) : 0); + mpEditor->Viewport()->CollisionRenderSettings().HighlightMask = Mask; +} + +void CCollisionRenderSettingsDialog::OnWireframeToggled(bool Enable) +{ + mpEditor->Viewport()->CollisionRenderSettings().DrawWireframe = Enable; +} diff --git a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.h b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.h new file mode 100644 index 00000000..826e230a --- /dev/null +++ b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.h @@ -0,0 +1,29 @@ +#ifndef CCOLLISIONRENDERSETTINGSDIALOG_H +#define CCOLLISIONRENDERSETTINGSDIALOG_H + +#include + +class CWorldEditor; + +namespace Ui { +class CCollisionRenderSettingsDialog; +} + +class CCollisionRenderSettingsDialog : public QDialog +{ + Q_OBJECT + Ui::CCollisionRenderSettingsDialog *mpUi; + + CWorldEditor *mpEditor; + +public: + explicit CCollisionRenderSettingsDialog(CWorldEditor *pEditor, QWidget *pParent = 0); + ~CCollisionRenderSettingsDialog(); + +public slots: + void OnHideMaskChanged(QString NewMask); + void OnHighlightMaskChanged(QString NewMask); + void OnWireframeToggled(bool Enable); +}; + +#endif // CCOLLISIONRENDERSETTINGSDIALOG_H diff --git a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.ui b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.ui new file mode 100644 index 00000000..58d9d443 --- /dev/null +++ b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.ui @@ -0,0 +1,59 @@ + + + CCollisionRenderSettingsDialog + + + + 0 + 0 + 309 + 89 + + + + Dialog + + + + + + + + Hide Mask + + + + + + + + + + Highlight Mask + + + + + + + + + + Wireframe + + + + + + + + + + + + + + + + + diff --git a/src/Editor/WorldEditor/CWorldEditor.cpp b/src/Editor/WorldEditor/CWorldEditor.cpp index e708bd79..e0cd3b7e 100644 --- a/src/Editor/WorldEditor/CWorldEditor.cpp +++ b/src/Editor/WorldEditor/CWorldEditor.cpp @@ -34,6 +34,7 @@ CWorldEditor::CWorldEditor(QWidget *parent) , ui(new Ui::CWorldEditor) , mpArea(nullptr) , mpWorld(nullptr) + , mpCollisionDialog(new CCollisionRenderSettingsDialog(this, this)) , mpLinkDialog(new CLinkDialog(this, this)) , mpPoiDialog(nullptr) , mIsMakingLink(false) @@ -139,6 +140,7 @@ CWorldEditor::CWorldEditor(QWidget *parent) connect(ui->ActionBloom, SIGNAL(triggered()), this, SLOT(SetBloom())); connect(ui->ActionIncrementGizmo, SIGNAL(triggered()), this, SLOT(IncrementGizmo())); connect(ui->ActionDecrementGizmo, SIGNAL(triggered()), this, SLOT(DecrementGizmo())); + connect(ui->ActionCollisionRenderSettings, SIGNAL(triggered()), this, SLOT(EditCollisionRenderSettings())); connect(ui->ActionEditLayers, SIGNAL(triggered()), this, SLOT(EditLayers())); connect(ui->ActionEditPoiToWorldMap, SIGNAL(triggered()), this, SLOT(EditPoiToWorldMap())); @@ -1104,6 +1106,11 @@ void CWorldEditor::DecrementGizmo() mGizmo.DecrementSize(); } +void CWorldEditor::EditCollisionRenderSettings() +{ + mpCollisionDialog->show(); +} + void CWorldEditor::EditLayers() { // Launch layer editor diff --git a/src/Editor/WorldEditor/CWorldEditor.h b/src/Editor/WorldEditor/CWorldEditor.h index 51e39f9a..766ca61a 100644 --- a/src/Editor/WorldEditor/CWorldEditor.h +++ b/src/Editor/WorldEditor/CWorldEditor.h @@ -1,6 +1,7 @@ #ifndef CWORLDEDITOR_H #define CWORLDEDITOR_H +#include "CCollisionRenderSettingsDialog.h" #include "CLinkDialog.h" #include "CPoiMapEditDialog.h" #include "Editor/INodeEditor.h" @@ -39,6 +40,7 @@ class CWorldEditor : public INodeEditor TResPtr mpArea; QTimer mRefreshTimer; + CCollisionRenderSettingsDialog *mpCollisionDialog; CLinkDialog *mpLinkDialog; CPoiMapEditDialog *mpPoiDialog; @@ -132,6 +134,7 @@ private slots: void SetBloom(); void IncrementGizmo(); void DecrementGizmo(); + void EditCollisionRenderSettings(); void EditLayers(); void EditPoiToWorldMap(); diff --git a/src/Editor/WorldEditor/CWorldEditor.ui b/src/Editor/WorldEditor/CWorldEditor.ui index 073fc5c9..b63382ac 100644 --- a/src/Editor/WorldEditor/CWorldEditor.ui +++ b/src/Editor/WorldEditor/CWorldEditor.ui @@ -463,6 +463,7 @@ + @@ -818,6 +819,11 @@ Ctrl+Shift+S + + + Collision Render Settings + + From 08dee8436759901a0c35176c4a6493d47c539c8c Mon Sep 17 00:00:00 2001 From: parax0 Date: Wed, 11 Jan 2017 06:29:30 -0700 Subject: [PATCH 05/10] Set up game-neutral collision materials; Jump Not Allowed flag now flags that surface as unstandable; other minor fixes --- resources/shaders/CollisionShader.vs | 8 ++ src/Core/Core.pro | 6 +- src/Core/Render/CDrawUtil.cpp | 11 ++- src/Core/Render/CDrawUtil.h | 2 +- src/Core/Render/SViewInfo.h | 19 +++-- src/Core/Resource/CCollisionMaterial.cpp | 66 +++++++++++++++++ src/Core/Resource/CCollisionMaterial.h | 64 ++++++++++++++++ src/Core/Resource/CCollisionMesh.cpp | 2 +- src/Core/Resource/CCollisionMesh.h | 17 +---- .../Resource/Factory/CCollisionLoader.cpp | 68 ++++++++++++++--- src/Core/Resource/Script/CScriptTemplate.cpp | 1 + src/Core/Scene/CCollisionNode.cpp | 74 +++++++------------ src/Editor/CAboutDialog.ui | 2 +- 13 files changed, 255 insertions(+), 85 deletions(-) create mode 100644 src/Core/Resource/CCollisionMaterial.cpp create mode 100644 src/Core/Resource/CCollisionMaterial.h diff --git a/resources/shaders/CollisionShader.vs b/resources/shaders/CollisionShader.vs index 88a16699..92ac2424 100644 --- a/resources/shaders/CollisionShader.vs +++ b/resources/shaders/CollisionShader.vs @@ -15,6 +15,9 @@ layout(std140) uniform MVPBlock mat4 ProjMtx; }; +uniform bool IsFloor; +uniform bool IsUnstandable; + // Main void main() { @@ -31,4 +34,9 @@ void main() float Alpha = (-LightDot + 1.0) / 2; float LightAlpha = mix(kLightColorMin, kLightColorMax, Alpha); LightColor = vec4(LightAlpha, LightAlpha, LightAlpha, 1.0); + + // If this is not a floor, make the surface significantly darker + // The surface is considered a floor if IsFloor is true OR if the floor normal Z is greater than 0.85 + float FloorMul = (!IsUnstandable && (IsFloor || RawNormal.z > 0.85)) ? 1.0 : 0.5; + LightColor *= FloorMul; } diff --git a/src/Core/Core.pro b/src/Core/Core.pro index ce8ab25d..b1a24459 100644 --- a/src/Core/Core.pro +++ b/src/Core/Core.pro @@ -196,7 +196,8 @@ HEADERS += \ Resource/Factory/CSkinLoader.h \ Render/EDepthGroup.h \ Scene/CScriptAttachNode.h \ - ScriptExtra/CSandwormExtra.h + ScriptExtra/CSandwormExtra.h \ + Resource/CCollisionMaterial.h # Source Files SOURCES += \ @@ -283,4 +284,5 @@ SOURCES += \ Resource/Factory/CSkinLoader.cpp \ Resource/Model/EVertexAttribute.cpp \ Scene/CScriptAttachNode.cpp \ - ScriptExtra/CSandwormExtra.cpp + ScriptExtra/CSandwormExtra.cpp \ + Resource/CCollisionMaterial.cpp diff --git a/src/Core/Render/CDrawUtil.cpp b/src/Core/Render/CDrawUtil.cpp index 0a7e1e5e..f0a58a75 100644 --- a/src/Core/Render/CDrawUtil.cpp +++ b/src/Core/Render/CDrawUtil.cpp @@ -329,14 +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(); + // 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(); } diff --git a/src/Core/Render/CDrawUtil.h b/src/Core/Render/CDrawUtil.h index 6fe5ba3d..13014945 100644 --- a/src/Core/Render/CDrawUtil.h +++ b/src/Core/Render/CDrawUtil.h @@ -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); diff --git a/src/Core/Render/SViewInfo.h b/src/Core/Render/SViewInfo.h index c7fa1499..a3019493 100644 --- a/src/Core/Render/SViewInfo.h +++ b/src/Core/Render/SViewInfo.h @@ -6,21 +6,24 @@ #include #include -enum ECollisionDrawMode -{ - eCDM_Default, - eCDM_TintSurfaceType -}; - struct SCollisionRenderSettings { - ECollisionDrawMode DrawMode; u64 HighlightMask; u64 HideMask; bool DrawWireframe; + bool DrawBackfaces; + bool DrawAreaCollisionBounds; + bool TintWithSurfaceColor; + bool TintUnwalkableTris; SCollisionRenderSettings() - : DrawMode(eCDM_TintSurfaceType), HighlightMask(0), HideMask(0), DrawWireframe(false) {} + : HighlightMask(0) + , HideMask(0) + , DrawWireframe(true) + , DrawBackfaces(false) + , DrawAreaCollisionBounds(true) + , TintWithSurfaceColor(true) + , TintUnwalkableTris(false) {} }; struct SViewInfo diff --git a/src/Core/Resource/CCollisionMaterial.cpp b/src/Core/Resource/CCollisionMaterial.cpp new file mode 100644 index 00000000..7e6712a4 --- /dev/null +++ b/src/Core/Resource/CCollisionMaterial.cpp @@ -0,0 +1,66 @@ +#include "CCollisionMaterial.h" +#include "EGame.h" +#include + +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::map gkTypeToColor = { + { eCF_Stone, CColor::Integral(220, 215, 160) }, // Brownish/greenish color + { eCF_Metal, CColor::Integral(110, 110, 110) }, // Dark gray + { eCF_Grass, CColor::Integral( 90, 150, 70) }, // Green + { eCF_Ice, CColor::Integral(200, 255, 255) }, // Light blue + { eCF_MetalGrating, CColor::Integral(170, 170, 170) }, // Gray + { eCF_Phazon, CColor::Integral( 0, 128, 255) }, // Blue + { eCF_Dirt, CColor::Integral(150, 130, 120) }, // Brownish-gray + { eCF_Lava, CColor::Integral(200, 30, 30) }, // Red + { eCF_Snow, CColor::Integral(230, 255, 255) }, // *Very* light blue + { eCF_Glass, CColor::Integral( 20, 255, 190) }, // Greenish blue + { eCF_Shield, CColor::Integral(230, 250, 60) }, // Yellow + { eCF_Sand, CColor::Integral(230, 200, 170) }, // Light brown + { eCF_Wood, CColor::Integral(190, 140, 105) }, // Brown + { eCF_Organic, CColor::Integral(130, 130, 250) } // Purple +}; +CColor CCollisionMaterial::SurfaceColor(EGame Game) const +{ + ECollisionFlag SurfType = SurfaceType(Game); + auto FindColor = gkTypeToColor.find(SurfType); + return (FindColor == gkTypeToColor.end() ? CColor::skWhite : FindColor->second); +} diff --git a/src/Core/Resource/CCollisionMaterial.h b/src/Core/Resource/CCollisionMaterial.h new file mode 100644 index 00000000..bcb78114 --- /dev/null +++ b/src/Core/Resource/CCollisionMaterial.h @@ -0,0 +1,64 @@ +#ifndef CCOLLISIONMATERIAL +#define CCOLLISIONMATERIAL + +#include "EGame.h" +#include +#include + +// 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_Floor = 0x08000000, + eCF_AiBlock = 0x10000000, + eCF_JumpNotAllowed = 0x20000000, + eCF_SpiderBall = 0x40000000, + eCF_WallJump = 0x80000000 +}; + +class CCollisionMaterial : public TFlags +{ + friend class CCollisionLoader; + u64 mRawFlags; + +public: + ECollisionFlag SurfaceType(EGame Game) const; + CColor SurfaceColor(EGame Game) const; + + inline u64 RawFlags() const { return mRawFlags; } +}; + +#endif // CCOLLISIONMATERIAL + diff --git a/src/Core/Resource/CCollisionMesh.cpp b/src/Core/Resource/CCollisionMesh.cpp index a4cb86d9..d9c3ad0c 100644 --- a/src/Core/Resource/CCollisionMesh.cpp +++ b/src/Core/Resource/CCollisionMesh.cpp @@ -73,7 +73,7 @@ void CCollisionMesh::BufferGL() Verts[2] = pLineB->Vertices[1]; // Some faces have a property that indicates they need to be inverted - if (GetMaterial(pFace->MaterialIdx).FlippedTri) + if (GetMaterial(pFace->MaterialIdx) & eCF_FlippedTri) { u16 V0 = Verts[0]; Verts[0] = Verts[2]; diff --git a/src/Core/Resource/CCollisionMesh.h b/src/Core/Resource/CCollisionMesh.h index 051cf6ef..797f143e 100644 --- a/src/Core/Resource/CCollisionMesh.h +++ b/src/Core/Resource/CCollisionMesh.h @@ -1,22 +1,12 @@ #ifndef CCOLLISIONMESH_H #define CCOLLISIONMESH_H +#include "CCollisionMaterial.h" #include "CResource.h" #include "Core/OpenGL/CVertexBuffer.h" #include "Core/OpenGL/CIndexBuffer.h" #include -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; @@ -71,7 +61,7 @@ class CCollisionMesh CAABox mAABox; CCollisionOctree *mpOctree; - std::vector mMaterials; + std::vector mMaterials; std::vector mCollisionVertices; std::vector mCollisionLines; std::vector mCollisionFaces; @@ -92,7 +82,8 @@ public: void DrawWireframe(); inline u32 NumMaterials() const { return mMaterials.size(); } - inline SCollisionMaterial& GetMaterial(u32 Index) { return mMaterials[Index]; } + inline CCollisionMaterial& GetMaterial(u32 Index) { return mMaterials[Index]; } + inline const CAABox& BoundingBox() const { return mAABox; } }; #endif // CCOLLISIONMESH_H diff --git a/src/Core/Resource/Factory/CCollisionLoader.cpp b/src/Core/Resource/Factory/CCollisionLoader.cpp index e88629d4..c3bd78a6 100644 --- a/src/Core/Resource/Factory/CCollisionLoader.cpp +++ b/src/Core/Resource/Factory/CCollisionLoader.cpp @@ -38,24 +38,74 @@ void CCollisionLoader::ParseOBBNode(IInputStream& rDCLN) void CCollisionLoader::ReadPropertyFlags(IInputStream& rSrc) { - SCollisionMaterial Material; + CCollisionMaterial Material; + u64 RawFlags = (mVersion <= ePrime ? rSrc.ReadLong() : rSrc.ReadLongLong()); + Material.mRawFlags = RawFlags; - if (mVersion == ePrime) + if (mVersion <= ePrime) { - Material.RawFlags = rSrc.ReadLong(); - Material.FlippedTri = (Material.RawFlags >> 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 & 0x80000000) Material |= eCF_Floor; } - else if (mVersion == eEchoes) + else if (mVersion <= eCorruption) { - Material.RawFlags = rSrc.ReadLongLong(); - Material.FlippedTri = (Material.RawFlags >> 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 & 0x80000000) Material |= eCF_Floor; + + if (RawFlags & 0x0001000000000000) Material |= eCF_AiBlock; + if (RawFlags & 0x0400000000000000) Material |= eCF_JumpNotAllowed; + if (RawFlags & 0x2000000000000000) Material |= eCF_SpiderBall; + if (RawFlags & 0x4000000000000000) Material |= eCF_WallJump; } else if (mVersion == eReturns) { - Material.RawFlags = rSrc.ReadLongLong(); - Material.FlippedTri = (Material.RawFlags >> 28) & 0x1; + if (RawFlags & 0x10000000) Material |= eCF_FlippedTri; } mpMesh->mMaterials.push_back(Material); diff --git a/src/Core/Resource/Script/CScriptTemplate.cpp b/src/Core/Resource/Script/CScriptTemplate.cpp index d344410a..3e065cda 100644 --- a/src/Core/Resource/Script/CScriptTemplate.cpp +++ b/src/Core/Resource/Script/CScriptTemplate.cpp @@ -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 diff --git a/src/Core/Scene/CCollisionNode.cpp b/src/Core/Scene/CCollisionNode.cpp index 714a2da7..a2e2b61d 100644 --- a/src/Core/Scene/CCollisionNode.cpp +++ b/src/Core/Scene/CCollisionNode.cpp @@ -37,6 +37,13 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_TRUE); + // 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++) @@ -45,63 +52,22 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER for (u32 iMat = 0; iMat < pMesh->NumMaterials(); iMat++) { - SCollisionMaterial& rMat = pMesh->GetMaterial(iMat); + CCollisionMaterial& rMat = pMesh->GetMaterial(iMat); - if (rkViewInfo.CollisionSettings.HideMask != 0 && (rMat.RawFlags & rkViewInfo.CollisionSettings.HideMask) == rkViewInfo.CollisionSettings.HideMask) + if (rkViewInfo.CollisionSettings.HideMask != 0 && (rMat.RawFlags() & rkViewInfo.CollisionSettings.HideMask) == rkViewInfo.CollisionSettings.HideMask) continue; CColor Tint = BaseTint; - if (rkViewInfo.CollisionSettings.HighlightMask != 0 && (rMat.RawFlags & rkViewInfo.CollisionSettings.HighlightMask) == rkViewInfo.CollisionSettings.HighlightMask) + if (rkViewInfo.CollisionSettings.HighlightMask != 0 && (rMat.RawFlags() & rkViewInfo.CollisionSettings.HighlightMask) == rkViewInfo.CollisionSettings.HighlightMask) Tint *= CColor::skRed; - else if (mpCollision->Game() <= ePrime && rkViewInfo.CollisionSettings.DrawMode == eCDM_TintSurfaceType) - { - // Organic - if (rMat.RawFlags & 0x00800000) - Tint *= CColor::Integral(130, 130, 250); // Purple - // Wood - else if (rMat.RawFlags & 0x00400000) - Tint *= CColor::Integral(190, 140, 105); // Brown - // Sand - else if (rMat.RawFlags & 0x00020000) - Tint *= CColor::Integral(230, 200, 170); // Light Brown - // Shield - else if (rMat.RawFlags & 0x00010000) - Tint *= CColor::Integral(250, 230, 60); // Yellow - // Glass - else if (rMat.RawFlags & 0x00008000) - Tint *= CColor::Integral(20, 255, 190); // Greenish/Bluish - // Snow - else if (rMat.RawFlags & 0x00000800) - Tint *= CColor::Integral(230, 255, 255); // *Very* light blue - // Lava - else if (rMat.RawFlags & 0x00000200) - Tint *= CColor::Integral(200, 30, 30); // Red - // Rock - else if (rMat.RawFlags & 0x00000100) - Tint *= CColor::Integral(150, 130, 120); // Brownish-gray - // Phazon - else if (rMat.RawFlags & 0x00000080) - Tint *= CColor::Integral(0, 128, 255); // Blue - // Metal Grating - else if (rMat.RawFlags & 0x00000040) - Tint *= CColor::Integral(170, 170, 170); // Gray - // Ice - else if (rMat.RawFlags & 0x00000010) - Tint *= CColor::Integral(200, 255, 255); // Light blue - // Grass - else if (rMat.RawFlags & 0x00000008) - Tint *= CColor::Integral(90, 150, 70); // Green - // Metal - else if (rMat.RawFlags & 0x00000004) - Tint *= CColor::Integral(110, 110, 110); // Dark gray - // Stone - else if (rMat.RawFlags & 0x00000002) - Tint *= CColor::Integral(220, 215, 160); // Brown/green ish - } + else if (CollisionGame != eReturns && rkViewInfo.CollisionSettings.TintWithSurfaceColor) + Tint *= rMat.SurfaceColor(CollisionGame); - CDrawUtil::UseCollisionShader(Tint); + bool IsFloor = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.HasFlag(eCF_Floor) : true); + bool IsUnstandable = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.HasFlag(eCF_JumpNotAllowed) : false); + CDrawUtil::UseCollisionShader(IsFloor, IsUnstandable, Tint); pMesh->DrawMaterial(iMat); } } @@ -111,6 +77,16 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER CDrawUtil::UseColorShader(CColor::skTransparentBlack); mpCollision->DrawWireframe(); } + + // 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) + CDrawUtil::DrawWireCube( mpCollision->MeshByIndex(0)->BoundingBox(), CColor::skRed ); } SRayIntersection CCollisionNode::RayNodeIntersectTest(const CRay& /*rkRay*/, u32 /*AssetID*/, const SViewInfo& /*rkViewInfo*/) diff --git a/src/Editor/CAboutDialog.ui b/src/Editor/CAboutDialog.ui index d649bc6f..0a3031be 100644 --- a/src/Editor/CAboutDialog.ui +++ b/src/Editor/CAboutDialog.ui @@ -17,7 +17,7 @@ - <html><head/><body><p><span style=" font-size:12pt; font-weight:600;">%APP_FULL_NAME%</span></p><p>%APP_NAME% is developed by <span style=" font-weight:600;">Parax</span>.<br/>All the games it edits are developed by <span style=" font-weight:600;">Retro Studios</span> and published by <span style=" font-weight:600;">Nintendo</span>.</p><p>Special thanks to:</p><p><ul><li> The community at <span style=" font-weight:600;">Metroid2002</span> that contributed to reverse engineering the game and documenting its internals and file formats; in particular, <span style=" font-weight:600;">Antidote</span> and <span style=" font-weight:600;">jackoalan</span>, among others!</li><li> <span style=" font-weight:600;">Miles: </span>In addition to helping reverse engineer a few formats (in particular MLVL and MREA), also contributed greatly to putting together the script object templates and documenting object properties.</li><li> <span style=" font-weight:600;">Bearborg:</span> Lots of testing and feedback, plus the UI icons and some script object assets.</li><li> <span style=" font-weight:600;">Omega: </span>Script object assets.</li></ul>Check the <a href="http://www.metroid2002.com/retromodding/wiki/Retro_Modding_Wiki">Retro Modding Wiki</a> for file format documentation.</p><p>%APP_NAME% uses <span style=" font-weight:600;">Assimp</span> (Open Asset Import Library).<br/>Copyright © 2006-2015 assimp team<br/>All rights reserved.</p></body></html> + <html><head/><body><p><span style=" font-size:12pt; font-weight:600;">%APP_FULL_NAME%</span></p><p>%APP_NAME% is developed by <span style=" font-weight:600;">Aruki</span>.<br/>All the games it edits are developed by <span style=" font-weight:600;">Retro Studios</span> and published by <span style=" font-weight:600;">Nintendo</span>.</p><p>Special thanks to:</p><p><ul><li> The community at <span style=" font-weight:600;">Metroid2002</span> that contributed to reverse engineering the game and documenting its internals and file formats; in particular, <span style=" font-weight:600;">Antidote</span> and <span style=" font-weight:600;">jackoalan</span>, among others!</li><li> <span style=" font-weight:600;">Claris: </span>In addition to helping reverse engineer a few formats (in particular MLVL and MREA), also contributed greatly to putting together the script object templates and documenting object properties.</li><li> <span style=" font-weight:600;">Bearborg:</span> Lots of testing and feedback, plus the UI icons and some script object assets.</li><li> <span style=" font-weight:600;">Omega: </span>Script object assets.</li></ul>Check the <a href="http://www.metroid2002.com/retromodding/wiki/Retro_Modding_Wiki">Retro Modding Wiki</a> for file format documentation.</p><p>%APP_NAME% uses <span style=" font-weight:600;">Assimp</span> (Open Asset Import Library).<br/>Copyright © 2006-2015 assimp team<br/>All rights reserved.</p></body></html> true From 9f6687ca85ffbef68a8826e7c940cdb73d13390b Mon Sep 17 00:00:00 2001 From: parax0 Date: Wed, 11 Jan 2017 06:30:46 -0700 Subject: [PATCH 06/10] DKCR template updates --- templates/Properties.xml | 30 ++--- templates/dkcr/MasterTemplate.xml | 186 ++++++++++++++--------------- templates/dkcr/Script/AreaNode.xml | 17 +-- templates/dkcr/Script/AreaPath.xml | 4 +- 4 files changed, 120 insertions(+), 117 deletions(-) diff --git a/templates/Properties.xml b/templates/Properties.xml index f0b8042f..952b4c4c 100644 --- a/templates/Properties.xml +++ b/templates/Properties.xml @@ -1081,7 +1081,7 @@ - + @@ -2054,7 +2054,7 @@ - + @@ -2158,7 +2158,7 @@ - + @@ -2622,7 +2622,7 @@ - + @@ -3502,7 +3502,7 @@ - + @@ -4076,7 +4076,7 @@ - + @@ -5139,7 +5139,7 @@ - + @@ -5212,7 +5212,7 @@ - + @@ -6285,7 +6285,7 @@ - + @@ -6989,7 +6989,7 @@ - + @@ -7191,7 +7191,7 @@ - + @@ -8031,7 +8031,7 @@ - + @@ -8910,7 +8910,7 @@ - + @@ -10617,7 +10617,7 @@ - + @@ -10806,7 +10806,7 @@ - + diff --git a/templates/dkcr/MasterTemplate.xml b/templates/dkcr/MasterTemplate.xml index 553901eb..da55f1f7 100644 --- a/templates/dkcr/MasterTemplate.xml +++ b/templates/dkcr/MasterTemplate.xml @@ -178,13 +178,13 @@ - + - + - + @@ -210,57 +210,57 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -268,12 +268,12 @@ - - + + - + @@ -282,12 +282,12 @@ - - - - - - + + + + + + @@ -296,7 +296,7 @@ - + @@ -326,40 +326,40 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + diff --git a/templates/dkcr/Script/AreaNode.xml b/templates/dkcr/Script/AreaNode.xml index 89fdb0b7..f5094ea4 100644 --- a/templates/dkcr/Script/AreaNode.xml +++ b/templates/dkcr/Script/AreaNode.xml @@ -15,14 +15,14 @@ 0x24E6FE6B - - - - - - - - + + + + + + + + @@ -30,6 +30,7 @@ 0 + Seems to affect the number displayed on the file select screen for "last completed stage" 0.0, 0.0, 0.0 diff --git a/templates/dkcr/Script/AreaPath.xml b/templates/dkcr/Script/AreaPath.xml index 09d2b06e..892b263b 100644 --- a/templates/dkcr/Script/AreaPath.xml +++ b/templates/dkcr/Script/AreaPath.xml @@ -45,7 +45,9 @@ - + + 0xC27FFA8F + enabled enabled From a2762e034ea99410c6b1a9f36f87f4085f7bddb8 Mon Sep 17 00:00:00 2001 From: parax0 Date: Wed, 11 Jan 2017 08:30:40 -0700 Subject: [PATCH 07/10] Lots of collision surface color tweaking --- src/Core/Resource/CCollisionMaterial.cpp | 35 ++++++++++++++---------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/Core/Resource/CCollisionMaterial.cpp b/src/Core/Resource/CCollisionMaterial.cpp index 7e6712a4..046071bc 100644 --- a/src/Core/Resource/CCollisionMaterial.cpp +++ b/src/Core/Resource/CCollisionMaterial.cpp @@ -43,20 +43,27 @@ ECollisionFlag CCollisionMaterial::SurfaceType(EGame Game) const // Type-to-color mappings const std::map gkTypeToColor = { - { eCF_Stone, CColor::Integral(220, 215, 160) }, // Brownish/greenish color - { eCF_Metal, CColor::Integral(110, 110, 110) }, // Dark gray - { eCF_Grass, CColor::Integral( 90, 150, 70) }, // Green - { eCF_Ice, CColor::Integral(200, 255, 255) }, // Light blue - { eCF_MetalGrating, CColor::Integral(170, 170, 170) }, // Gray - { eCF_Phazon, CColor::Integral( 0, 128, 255) }, // Blue - { eCF_Dirt, CColor::Integral(150, 130, 120) }, // Brownish-gray - { eCF_Lava, CColor::Integral(200, 30, 30) }, // Red - { eCF_Snow, CColor::Integral(230, 255, 255) }, // *Very* light blue - { eCF_Glass, CColor::Integral( 20, 255, 190) }, // Greenish blue - { eCF_Shield, CColor::Integral(230, 250, 60) }, // Yellow - { eCF_Sand, CColor::Integral(230, 200, 170) }, // Light brown - { eCF_Wood, CColor::Integral(190, 140, 105) }, // Brown - { eCF_Organic, CColor::Integral(130, 130, 250) } // Purple + { 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 { From c62a01e4d938e6409a3da900e8cd6de3f62d60ed Mon Sep 17 00:00:00 2001 From: parax0 Date: Sat, 14 Jan 2017 10:32:41 -0700 Subject: [PATCH 08/10] Added a couple more collision view features; set up a proper UI for changing collision render settings --- src/Core/Render/SViewInfo.h | 5 +- src/Core/Resource/CCollisionMaterial.cpp | 4 +- src/Core/Resource/CCollisionMesh.cpp | 13 +- src/Core/Resource/CCollisionMesh.h | 2 +- src/Core/Scene/CCollisionNode.cpp | 22 +-- .../CCollisionRenderSettingsDialog.cpp | 75 ++++++++ .../CCollisionRenderSettingsDialog.h | 6 + .../CCollisionRenderSettingsDialog.ui | 170 ++++++++++++++---- src/Editor/WorldEditor/CWorldEditor.cpp | 11 +- src/Editor/WorldEditor/CWorldEditor.h | 1 - src/Editor/WorldEditor/CWorldEditor.ui | 1 - 11 files changed, 246 insertions(+), 64 deletions(-) diff --git a/src/Core/Render/SViewInfo.h b/src/Core/Render/SViewInfo.h index a3019493..2c75e3d0 100644 --- a/src/Core/Render/SViewInfo.h +++ b/src/Core/Render/SViewInfo.h @@ -1,6 +1,7 @@ #ifndef SVIEWINFO #define SVIEWINFO +#include "Core/Resource/CCollisionMaterial.h" #include "Core/Scene/FShowFlags.h" #include #include @@ -10,6 +11,8 @@ struct SCollisionRenderSettings { u64 HighlightMask; u64 HideMask; + + CCollisionMaterial HideMaterial; bool DrawWireframe; bool DrawBackfaces; bool DrawAreaCollisionBounds; @@ -23,7 +26,7 @@ struct SCollisionRenderSettings , DrawBackfaces(false) , DrawAreaCollisionBounds(true) , TintWithSurfaceColor(true) - , TintUnwalkableTris(false) {} + , TintUnwalkableTris(true) {} }; struct SViewInfo diff --git a/src/Core/Resource/CCollisionMaterial.cpp b/src/Core/Resource/CCollisionMaterial.cpp index 046071bc..c7e5abcd 100644 --- a/src/Core/Resource/CCollisionMaterial.cpp +++ b/src/Core/Resource/CCollisionMaterial.cpp @@ -1,6 +1,6 @@ #include "CCollisionMaterial.h" #include "EGame.h" -#include +#include ECollisionFlag CCollisionMaterial::SurfaceType(EGame Game) const { @@ -42,7 +42,7 @@ ECollisionFlag CCollisionMaterial::SurfaceType(EGame Game) const } // Type-to-color mappings -const std::map gkTypeToColor = { +const std::unordered_map 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 diff --git a/src/Core/Resource/CCollisionMesh.cpp b/src/Core/Resource/CCollisionMesh.cpp index d9c3ad0c..dc85a462 100644 --- a/src/Core/Resource/CCollisionMesh.cpp +++ b/src/Core/Resource/CCollisionMesh.cpp @@ -122,7 +122,7 @@ void CCollisionMesh::Draw() mVBO.Unbind(); } -void CCollisionMesh::DrawMaterial(u32 MatIdx) +void CCollisionMesh::DrawMaterial(u32 MatIdx, bool Wireframe) { if (!mBuffered) BufferGL(); ASSERT(MatIdx < mMaterials.size()); @@ -130,7 +130,18 @@ void CCollisionMesh::DrawMaterial(u32 MatIdx) 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(); } diff --git a/src/Core/Resource/CCollisionMesh.h b/src/Core/Resource/CCollisionMesh.h index 797f143e..bd9bbe59 100644 --- a/src/Core/Resource/CCollisionMesh.h +++ b/src/Core/Resource/CCollisionMesh.h @@ -78,7 +78,7 @@ public: void BufferGL(); void Draw(); - void DrawMaterial(u32 MatIdx); + void DrawMaterial(u32 MatIdx, bool Wireframe); void DrawWireframe(); inline u32 NumMaterials() const { return mMaterials.size(); } diff --git a/src/Core/Scene/CCollisionNode.cpp b/src/Core/Scene/CCollisionNode.cpp index a2e2b61d..fcd0b65b 100644 --- a/src/Core/Scene/CCollisionNode.cpp +++ b/src/Core/Scene/CCollisionNode.cpp @@ -54,7 +54,10 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER { CCollisionMaterial& rMat = pMesh->GetMaterial(iMat); - if (rkViewInfo.CollisionSettings.HideMask != 0 && (rMat.RawFlags() & rkViewInfo.CollisionSettings.HideMask) == rkViewInfo.CollisionSettings.HideMask) + if (rkViewInfo.CollisionSettings.HideMaterial & rMat) + continue; + + if (rkViewInfo.CollisionSettings.HideMask != 0 && (rMat.RawFlags() & rkViewInfo.CollisionSettings.HideMask) != 0) continue; CColor Tint = BaseTint; @@ -65,17 +68,14 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER else if (CollisionGame != eReturns && rkViewInfo.CollisionSettings.TintWithSurfaceColor) Tint *= rMat.SurfaceColor(CollisionGame); - bool IsFloor = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.HasFlag(eCF_Floor) : true); - bool IsUnstandable = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.HasFlag(eCF_JumpNotAllowed) : false); + bool IsFloor = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.HasFlag(eCF_Floor) : true) || CollisionGame == eReturns; + bool IsUnstandable = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.HasFlag(eCF_JumpNotAllowed) : false) && CollisionGame != eReturns; CDrawUtil::UseCollisionShader(IsFloor, IsUnstandable, Tint); - pMesh->DrawMaterial(iMat); - } - } + pMesh->DrawMaterial(iMat, false); - if (rkViewInfo.CollisionSettings.DrawWireframe) - { - CDrawUtil::UseColorShader(CColor::skTransparentBlack); - mpCollision->DrawWireframe(); + if (rkViewInfo.CollisionSettings.DrawWireframe) + pMesh->DrawMaterial(iMat, true); + } } // Restore backface culling setting @@ -85,7 +85,7 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER // 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) + if (rkViewInfo.CollisionSettings.DrawAreaCollisionBounds && Parent()->NodeType() == eRootNode && CollisionGame != eReturns) CDrawUtil::DrawWireCube( mpCollision->MeshByIndex(0)->BoundingBox(), CColor::skRed ); } diff --git a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.cpp b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.cpp index 79f17e60..2a9589b8 100644 --- a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.cpp +++ b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.cpp @@ -10,9 +10,20 @@ CCollisionRenderSettingsDialog::CCollisionRenderSettingsDialog(CWorldEditor *pEd { mpUi->setupUi(this); + SetupWidgets(); connect(mpUi->HideMaskLineEdit, SIGNAL(textChanged(QString)), this, SLOT(OnHideMaskChanged(QString))); connect(mpUi->HighlightMaskLineEdit, SIGNAL(textChanged(QString)), this, SLOT(OnHighlightMaskChanged(QString))); connect(mpUi->WireframeCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnWireframeToggled(bool))); + connect(mpUi->SurfaceTypeCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnSurfaceTypeToggled(bool))); + connect(mpUi->StandableTrisCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnStandableTrisToggled(bool))); + connect(mpUi->AreaBoundsCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnAreaBoundsToggled(bool))); + connect(mpUi->BackfacesCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnBackfacesToggled(bool))); + + connect(mpUi->HideShootThruCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnHideCheckboxesToggled())); + connect(mpUi->HideCameraThruCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnHideCheckboxesToggled())); + connect(mpUi->HideScanThruCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnHideCheckboxesToggled())); + connect(mpUi->HideAiWalkThruCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnHideCheckboxesToggled())); + connect(mpUi->HideAiBlockCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnHideCheckboxesToggled())); } CCollisionRenderSettingsDialog::~CCollisionRenderSettingsDialog() @@ -20,6 +31,40 @@ CCollisionRenderSettingsDialog::~CCollisionRenderSettingsDialog() delete mpUi; } +void CCollisionRenderSettingsDialog::SetupWidgets() +{ + SCollisionRenderSettings& rSettings = mpEditor->Viewport()->CollisionRenderSettings(); + EGame Game = mpEditor->CurrentGame(); + + // Set widgets to match current render setting values + mpUi->HideMaskLineEdit->setText( "0x" + QString::number(rSettings.HideMask, 16).toUpper() ); + mpUi->HighlightMaskLineEdit->setText( "0x" + QString::number(rSettings.HighlightMask, 16).toUpper() ); + mpUi->WireframeCheckBox->setChecked(rSettings.DrawWireframe); + mpUi->SurfaceTypeCheckBox->setChecked(rSettings.TintWithSurfaceColor); + mpUi->StandableTrisCheckBox->setChecked(rSettings.TintUnwalkableTris); + mpUi->AreaBoundsCheckBox->setChecked(rSettings.DrawAreaCollisionBounds); + mpUi->BackfacesCheckBox->setChecked(rSettings.DrawBackfaces); + + mpUi->HideShootThruCheckBox->setChecked(rSettings.HideMaterial.HasFlag(eCF_ShootThru)); + mpUi->HideCameraThruCheckBox->setChecked(rSettings.HideMaterial.HasFlag(eCF_CameraThru)); + mpUi->HideScanThruCheckBox->setChecked(rSettings.HideMaterial.HasFlag(eCF_ScanThru)); + mpUi->HideAiWalkThruCheckBox->setChecked(rSettings.HideMaterial.HasFlag(eCF_AiWalkThru)); + mpUi->HideAiBlockCheckBox->setChecked(rSettings.HideMaterial.HasFlag(eCF_AiBlock)); + + // Toggle visibility of game-exclusive widgets + mpUi->SurfaceTypeCheckBox->setHidden( Game == eReturns ); + mpUi->StandableTrisCheckBox->setHidden( Game == eReturns ); + mpUi->AreaBoundsCheckBox->setHidden( Game == eReturns ); + mpUi->BackfacesCheckBox->setHidden( Game == eReturns ); + + mpUi->VisibilityGroupBox->setHidden( Game == eReturns ); + mpUi->HideShootThruCheckBox->setHidden( Game == eReturns ); + mpUi->HideCameraThruCheckBox->setHidden( Game == eReturns ); + mpUi->HideScanThruCheckBox->setHidden( Game == eReturns ); + mpUi->HideAiWalkThruCheckBox->setHidden( Game == eReturns ); + mpUi->HideAiBlockCheckBox->setHidden( Game < eEchoesDemo || Game == eReturns ); +} + void CCollisionRenderSettingsDialog::OnHideMaskChanged(QString NewMask) { TString MaskStr = TO_TSTRING(NewMask); @@ -38,3 +83,33 @@ void CCollisionRenderSettingsDialog::OnWireframeToggled(bool Enable) { mpEditor->Viewport()->CollisionRenderSettings().DrawWireframe = Enable; } + +void CCollisionRenderSettingsDialog::OnSurfaceTypeToggled(bool Enable) +{ + mpEditor->Viewport()->CollisionRenderSettings().TintWithSurfaceColor = Enable; +} + +void CCollisionRenderSettingsDialog::OnStandableTrisToggled(bool Enable) +{ + mpEditor->Viewport()->CollisionRenderSettings().TintUnwalkableTris = Enable; +} + +void CCollisionRenderSettingsDialog::OnAreaBoundsToggled(bool Enable) +{ + mpEditor->Viewport()->CollisionRenderSettings().DrawAreaCollisionBounds = Enable; +} + +void CCollisionRenderSettingsDialog::OnBackfacesToggled(bool Enable) +{ + mpEditor->Viewport()->CollisionRenderSettings().DrawBackfaces = Enable; +} + +void CCollisionRenderSettingsDialog::OnHideCheckboxesToggled() +{ + CCollisionMaterial& rMat = mpEditor->Viewport()->CollisionRenderSettings().HideMaterial; + mpUi->HideShootThruCheckBox->isChecked() ? rMat |= eCF_ShootThru : rMat &= ~eCF_ShootThru; + mpUi->HideCameraThruCheckBox->isChecked() ? rMat |= eCF_CameraThru : rMat &= ~eCF_CameraThru; + mpUi->HideScanThruCheckBox->isChecked() ? rMat |= eCF_ScanThru : rMat &= ~eCF_ScanThru; + mpUi->HideAiWalkThruCheckBox->isChecked() ? rMat |= eCF_AiWalkThru : rMat &= ~eCF_AiWalkThru; + mpUi->HideAiBlockCheckBox->isChecked() ? rMat |= eCF_AiBlock : rMat &= ~eCF_AiBlock; +} diff --git a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.h b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.h index 826e230a..6219dce2 100644 --- a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.h +++ b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.h @@ -21,9 +21,15 @@ public: ~CCollisionRenderSettingsDialog(); public slots: + void SetupWidgets(); void OnHideMaskChanged(QString NewMask); void OnHighlightMaskChanged(QString NewMask); void OnWireframeToggled(bool Enable); + void OnSurfaceTypeToggled(bool Enable); + void OnStandableTrisToggled(bool Enable); + void OnAreaBoundsToggled(bool Enable); + void OnBackfacesToggled(bool Enable); + void OnHideCheckboxesToggled(); }; #endif // CCOLLISIONRENDERSETTINGSDIALOG_H diff --git a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.ui b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.ui index 58d9d443..d37c78bb 100644 --- a/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.ui +++ b/src/Editor/WorldEditor/CCollisionRenderSettingsDialog.ui @@ -6,51 +6,143 @@ 0 0 - 309 - 89 + 247 + 395 + + + 0 + 0 + + - Dialog + Collision Render Settings + + QLayout::SetFixedSize + - - - - - Hide Mask - - - - - - - - - - Highlight Mask - - - - - - - - - - Wireframe - - - - - - - - - - - + + + Settings + + + + + + Wireframe + + + + + + + Show Standable Tris + + + + + + + Show Surface Type + + + + + + + Show Area Collision Bounds + + + + + + + Draw Backfaces + + + + + + + + + + Visibility + + + + + + Hide Shoot Thru + + + + + + + Hide Camera Thru + + + + + + + Hide Scan Thru + + + + + + + Hide AI Walk Thru + + + + + + + Hide AI Block + + + + + + + + + + Advanced + + + + + + + + Hide Mask + + + + + + + + + + Highlight Mask + + + + + + + + + + diff --git a/src/Editor/WorldEditor/CWorldEditor.cpp b/src/Editor/WorldEditor/CWorldEditor.cpp index e0cd3b7e..cbe2e847 100644 --- a/src/Editor/WorldEditor/CWorldEditor.cpp +++ b/src/Editor/WorldEditor/CWorldEditor.cpp @@ -34,7 +34,6 @@ CWorldEditor::CWorldEditor(QWidget *parent) , ui(new Ui::CWorldEditor) , mpArea(nullptr) , mpWorld(nullptr) - , mpCollisionDialog(new CCollisionRenderSettingsDialog(this, this)) , mpLinkDialog(new CLinkDialog(this, this)) , mpPoiDialog(nullptr) , mIsMakingLink(false) @@ -93,6 +92,8 @@ CWorldEditor::CWorldEditor(QWidget *parent) ui->ActionDelete->setAutoRepeat(false); ui->ActionDelete->setShortcut(QKeySequence::Delete); + mpCollisionDialog = new CCollisionRenderSettingsDialog(this, this); + // Connect signals and slots connect(ui->MainViewport, SIGNAL(ViewportClick(SRayIntersection,QMouseEvent*)), this, SLOT(OnViewportClick(SRayIntersection,QMouseEvent*))); connect(ui->MainViewport, SIGNAL(InputProcessed(SRayIntersection,QMouseEvent*)), this, SLOT(OnViewportInputProcessed(SRayIntersection,QMouseEvent*))); @@ -129,7 +130,6 @@ CWorldEditor::CWorldEditor(QWidget *parent) connect(ui->ActionDrawLights, SIGNAL(triggered()), this, SLOT(ToggleDrawLights())); connect(ui->ActionDrawSky, SIGNAL(triggered()), this, SLOT(ToggleDrawSky())); connect(ui->ActionGameMode, SIGNAL(triggered()), this, SLOT(ToggleGameMode())); - connect(ui->ActionDisableBackfaceCull, SIGNAL(triggered()), this, SLOT(ToggleBackfaceCull())); connect(ui->ActionDisableAlpha, SIGNAL(triggered()), this, SLOT(ToggleDisableAlpha())); connect(ui->ActionNoLighting, SIGNAL(triggered()), this, SLOT(SetNoLighting())); connect(ui->ActionBasicLighting, SIGNAL(triggered()), this, SLOT(SetBasicLighting())); @@ -162,6 +162,7 @@ void CWorldEditor::closeEvent(QCloseEvent *pEvent) if (ShouldClose) { mUndoStack.clear(); + mpCollisionDialog->close(); mpLinkDialog->close(); if (mpPoiDialog) @@ -228,6 +229,7 @@ void CWorldEditor::SetArea(CWorld *pWorld, CGameArea *pArea) ui->InstancesTabContents->SetMaster(pMaster); // Set up dialogs + mpCollisionDialog->SetupWidgets(); // Won't modify any settings but will update widget visibility status if we've changed games mpLinkDialog->SetMaster(pMaster); // Set window title @@ -1026,11 +1028,6 @@ void CWorldEditor::ToggleGameMode() ui->MainViewport->SetGameMode(ui->ActionGameMode->isChecked()); } -void CWorldEditor::ToggleBackfaceCull() -{ - ui->MainViewport->Renderer()->ToggleBackfaceCull(!ui->ActionDisableBackfaceCull->isChecked()); -} - void CWorldEditor::ToggleDisableAlpha() { ui->MainViewport->Renderer()->ToggleAlphaDisabled(ui->ActionDisableAlpha->isChecked()); diff --git a/src/Editor/WorldEditor/CWorldEditor.h b/src/Editor/WorldEditor/CWorldEditor.h index 766ca61a..c70eda2c 100644 --- a/src/Editor/WorldEditor/CWorldEditor.h +++ b/src/Editor/WorldEditor/CWorldEditor.h @@ -123,7 +123,6 @@ private slots: void ToggleDrawLights(); void ToggleDrawSky(); void ToggleGameMode(); - void ToggleBackfaceCull(); void ToggleDisableAlpha(); void SetNoLighting(); void SetBasicLighting(); diff --git a/src/Editor/WorldEditor/CWorldEditor.ui b/src/Editor/WorldEditor/CWorldEditor.ui index b63382ac..ae3e34d6 100644 --- a/src/Editor/WorldEditor/CWorldEditor.ui +++ b/src/Editor/WorldEditor/CWorldEditor.ui @@ -464,7 +464,6 @@ - From 7cc8e2a0c984d955e3689448cddd29b594e2b1cd Mon Sep 17 00:00:00 2001 From: parax0 Date: Mon, 16 Jan 2017 01:02:03 -0700 Subject: [PATCH 09/10] Updated version number for public release --- src/.qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/.qmake.conf b/src/.qmake.conf index 873372a5..17aef713 100644 --- a/src/.qmake.conf +++ b/src/.qmake.conf @@ -1,7 +1,7 @@ # CONFIG += PUBLIC_RELEASE DEFINES += 'APP_NAME=\"\\\"Prime World Editor\\\"\"' \ - 'APP_VERSION=\"\\\"1.1.0\\\"\"' + 'APP_VERSION=\"\\\"1.1.1\\\"\"' PUBLIC_RELEASE { DEFINES += 'PUBLIC_RELEASE=1' \ From 57c2830b04d25a39ce89c576bfb9690f7eaf99f0 Mon Sep 17 00:00:00 2001 From: parax0 Date: Sun, 29 Jan 2017 05:01:41 -0700 Subject: [PATCH 10/10] Fixes for standable collision tris visualization in Metroid Prime 3 --- src/Core/Resource/CCollisionMaterial.cpp | 12 ++++++++++++ src/Core/Resource/CCollisionMaterial.h | 12 +++++++----- src/Core/Resource/Factory/CCollisionLoader.cpp | 6 ++++-- src/Core/Scene/CCollisionNode.cpp | 4 ++-- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/Core/Resource/CCollisionMaterial.cpp b/src/Core/Resource/CCollisionMaterial.cpp index c7e5abcd..0a23e4aa 100644 --- a/src/Core/Resource/CCollisionMaterial.cpp +++ b/src/Core/Resource/CCollisionMaterial.cpp @@ -1,5 +1,6 @@ #include "CCollisionMaterial.h" #include "EGame.h" +#include #include ECollisionFlag CCollisionMaterial::SurfaceType(EGame Game) const @@ -71,3 +72,14 @@ CColor CCollisionMaterial::SurfaceColor(EGame Game) const 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 +{ + BREAK_ONLY_ASSERT(!HasFlag(eCF_Wood)); + return HasFlag(eCF_JumpNotAllowed) || (Game >= eEchoesDemo && !HasFlag(eCF_Floor) && HasAnyFlags(eCF_Wall | eCF_Ceiling)); +} diff --git a/src/Core/Resource/CCollisionMaterial.h b/src/Core/Resource/CCollisionMaterial.h index bcb78114..d07be371 100644 --- a/src/Core/Resource/CCollisionMaterial.h +++ b/src/Core/Resource/CCollisionMaterial.h @@ -41,11 +41,11 @@ enum ECollisionFlag eCF_ScanThru = 0x01000000, eCF_AiWalkThru = 0x02000000, eCF_FlippedTri = 0x04000000, - eCF_Floor = 0x08000000, - eCF_AiBlock = 0x10000000, - eCF_JumpNotAllowed = 0x20000000, - eCF_SpiderBall = 0x40000000, - eCF_WallJump = 0x80000000 + eCF_Ceiling = 0x08000000, + eCF_Wall = 0x10000000, + eCF_Floor = 0x20000000, + eCF_AiBlock = 0x40000000, + eCF_JumpNotAllowed = 0x80000000 }; class CCollisionMaterial : public TFlags @@ -56,6 +56,8 @@ class CCollisionMaterial : public TFlags 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; } }; diff --git a/src/Core/Resource/Factory/CCollisionLoader.cpp b/src/Core/Resource/Factory/CCollisionLoader.cpp index c3bd78a6..4f122537 100644 --- a/src/Core/Resource/Factory/CCollisionLoader.cpp +++ b/src/Core/Resource/Factory/CCollisionLoader.cpp @@ -66,6 +66,8 @@ void CCollisionLoader::ReadPropertyFlags(IInputStream& rSrc) 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; } @@ -95,12 +97,12 @@ void CCollisionLoader::ReadPropertyFlags(IInputStream& rSrc) 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; - if (RawFlags & 0x2000000000000000) Material |= eCF_SpiderBall; - if (RawFlags & 0x4000000000000000) Material |= eCF_WallJump; } else if (mVersion == eReturns) diff --git a/src/Core/Scene/CCollisionNode.cpp b/src/Core/Scene/CCollisionNode.cpp index fcd0b65b..8e549e0c 100644 --- a/src/Core/Scene/CCollisionNode.cpp +++ b/src/Core/Scene/CCollisionNode.cpp @@ -68,8 +68,8 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER else if (CollisionGame != eReturns && rkViewInfo.CollisionSettings.TintWithSurfaceColor) Tint *= rMat.SurfaceColor(CollisionGame); - bool IsFloor = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.HasFlag(eCF_Floor) : true) || CollisionGame == eReturns; - bool IsUnstandable = (rkViewInfo.CollisionSettings.TintUnwalkableTris ? rMat.HasFlag(eCF_JumpNotAllowed) : false) && CollisionGame != eReturns; + 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);