Cry Legacy: the Lessening (#5961)

* Generic Cleanup

Removals:

* Unused cvars,member variables and defines
* Windows media center edition support routines
* CSystem - removed debug_GetCallStackRaw/GetRootWindowMessageHandler/
UnloadDLL/ShutdownModuleLibraries

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Fix CryMessageBox return values in Windows build

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove named selection group and a few smaller unused functionalities

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove ObjectManager export functionality + 2 deprecated functions

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove object legacy freeze/hide support from ObjectManager

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove ObjectManager duplicate name dection, as well as object renaming

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove ObjectManager serialization and selection callbacks

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* ObjectManager - remove MoveObjects/HitTestObject/EndEditParams and related members/functions

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove a bunch of unused clone related functionality + misc

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* ObjectManager - misc removals

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* ObjectManager - more removals

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove unused object selection/retrieval in ObjectManager and LoadObjects in ObjectLoader

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* CBaseObject - remove unused material layers mask support

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* More CBaseObject cleanups.

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* CBaseObject - remove SubObj functions and IMouseCreateCallback

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove unused procedural floor management, helper scale and tags.

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* CBaseObject - remove more unused methods.

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Removals in multiple places.

CBaseObject - unused `OBJTYPE_DUMMY` flag removed, member `IsSameClass`
CObjectArchive removed unused methods/members
CObjectManager removed unused `Update` method

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* More removals

IDisplayViewport - HitTestLine/GetGridStep/setHitcontext/
GetConstructionPlane
Unused Cry_Matrix44 template specializations.

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* O3DE.exe Project-Centric "Open Editor" fix (#5852)

* The O3DE.exe Open Editor button now attempts to open the Editor in the
build directory of the project being opened.

If their is no Editor within the build directory of the Project, it uses
the Editor.exe in the current O3DE.exe executable directory if it exists

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Engine .gitignore now ignores the build directory if placed in the
AutomatedTesting project

Previously it was just ignoring a `[Bb]uild` directory if it was
directly within the engine root.
This change matches the behavior of the project templates.

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Renamed the ProjectUtils GetEditorDirectory function to
GetEditorExecutablePath

Added a platform specific implementation for retrieving the path to the
Editor executable in the GetEditorExectuablePath function.

It first attempts to locate the Editor via checking the project build
directory for an Editor executable before falling back to checking the
binary directory of the currently running O3DE executable.

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Correct the MacOS GetEditorExecutablePath to return the Editor path

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Adding missing C++20 std::erase implementations (#5735)

There were already implementations for std::erase_if.
This adds the counterpart AZStd::erase versions

resolves #5734

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* More removals and refactors

`ShowMessage` and `CryMessageBox` return void now
Simplify code in `CSystem::WarningV`
Remove unused `CryGetTicksPerSec`
Remove unused WinBase functionality
Replace `nanosleep` call in WinBase with `std::this_thread::sleep_for`
Remove unused Win32Wrapper routines
Remove unused IFunctorBase.h and IEntityObjectListener.h
Fix VectorAndArray.cpp compilation
Use QMessageBox instead of CryMessageBox in the editor.
Remove empty ArchiveVars platform specific files

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Fix test code.

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove an unused  function

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* CBaseObject and undo description removals.

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* A bunch of removals

* Remove IRenderNode
* Remove editor's KDTree
* Remove StatObjBus, InstanceStatObjEventBus::ReleaseData is redundant (
same functionality in the only available handler is triggered by
`OnCryEditorCloseScene`)
* Remove CExportManager::AddStatObj/AddMeshes/AddMesh,
IExportManager::ExportSingleStatObj
* Remove CIconManager/IIconManager::GetObject
* Remove CBaseObject::IntersectRayMesh
* Remove IIndexedMesh and related structs.
* Unused IUndoObject::GetDescription and all derived implementations.
* Unused CUndoBaseLibrary/CUndoBaseLibraryManager
* Unused Matrix34_tpl typedefs
* Legacy Xml classes cleanup

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* Remove unused `Vec3ToVector3D` helper

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

* fix - remove unused static variable

Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com>

Co-authored-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
This commit is contained in:
Artur K
2021-11-29 19:21:06 +01:00
committed by GitHub
parent a3835d8545
commit 56904d1799
115 changed files with 355 additions and 6354 deletions
-572
View File
@@ -1,572 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "KDTree.h"
#include <IStatObj.h>
class KDTreeNode
{
public:
KDTreeNode()
{
pChildren[0] = nullptr;
pChildren[1] = nullptr;
pVertexIndices = nullptr;
}
~KDTreeNode()
{
if (!IsLeaf())
{
if (pChildren[0])
{
delete pChildren[0];
}
if (pChildren[1])
{
delete pChildren[1];
}
}
else if (GetVertexBufferSize() > 1)
{
if (pVertexIndices)
{
delete [] pVertexIndices;
}
}
}
uint32 GetVertexBufferSize() const
{
return nVertexIndexBufferSize;
}
float GetSplitPos() const
{
return splitPos;
}
void SetSplitPos(float pos)
{
splitPos = pos;
}
CKDTree::ESplitAxis GetSplitAxis() const
{
if (splitAxis == 0)
{
return CKDTree::eSA_X;
}
if (splitAxis == 1)
{
return CKDTree::eSA_Y;
}
if (splitAxis == 2)
{
return CKDTree::eSA_Z;
}
return CKDTree::eSA_Invalid;
}
void SetSplitAxis(const CKDTree::ESplitAxis& axis)
{
splitAxis = axis;
}
bool IsLeaf() const
{
return pChildren[0] == nullptr && pChildren[1] == nullptr;
}
KDTreeNode* GetChild(uint32 nIndex) const
{
if (nIndex > 1)
{
return nullptr;
}
return pChildren[nIndex];
}
void SetChild(uint32 nIndex, KDTreeNode* pNode)
{
if (nIndex > 1)
{
return;
}
if (pChildren[nIndex])
{
delete pChildren[nIndex];
}
pChildren[nIndex] = pNode;
}
const AABB& GetBoundBox()
{
return boundbox;
}
void SetBoundBox(const AABB& aabb)
{
boundbox = aabb;
}
void SetVertexIndexBuffer(std::vector<uint32>& vertexInfos)
{
nVertexIndexBufferSize = (uint32)vertexInfos.size();
if (nVertexIndexBufferSize == 0)
{
return;
}
if (nVertexIndexBufferSize == 1)
{
oneIndex = vertexInfos[0];
}
else
{
pVertexIndices = new uint32[nVertexIndexBufferSize];
memcpy(pVertexIndices, &vertexInfos[0], sizeof(uint32) * nVertexIndexBufferSize);
}
}
uint32 GetVertexIndex(uint32 nIndex) const
{
if (GetVertexBufferSize() == 1)
{
return oneIndex & 0x00FFFFFF;
}
return pVertexIndices[nIndex] & 0x00FFFFFF;
}
uint32 GetObjIndex(uint32 nIndex) const
{
if (GetVertexBufferSize() == 1)
{
return (oneIndex & 0xFF000000) >> 24;
}
return (pVertexIndices[nIndex] & 0xFF000000) >> 24;
}
private:
union
{
float splitPos; // Interior
uint32 oneIndex; // Leaf
uint32* pVertexIndices; // Leaf : high 8bits - object index, low 24bits - vertex index
};
union
{
uint32 splitAxis; // Interior
uint32 nVertexIndexBufferSize; // Leaf
};
AABB boundbox; // Both
KDTreeNode* pChildren[2]; // Interior
};
CKDTree::ESplitAxis SearchForBestSplitAxis(const AABB& aabb)
{
float xsize = aabb.max.x - aabb.min.x;
float ysize = aabb.max.y - aabb.min.y;
float zsize = aabb.max.z - aabb.min.z;
CKDTree::ESplitAxis axis;
if (xsize > ysize && xsize > zsize)
{
axis = CKDTree::eSA_X;
}
else if (ysize > zsize && ysize > xsize)
{
axis = CKDTree::eSA_Y;
}
else
{
axis = CKDTree::eSA_Z;
}
return axis;
}
bool SearchForBestSplitPos(CKDTree::ESplitAxis axis, const std::vector<CKDTree::SStatObj>& statObjList, std::vector<uint32>& indices, float& outBestSplitPos)
{
if (axis != CKDTree::eSA_X && axis != CKDTree::eSA_Y && axis != CKDTree::eSA_Z)
{
return false;
}
outBestSplitPos = 0;
int nSizeOfIndices = static_cast<int>(indices.size());
for (int i = 0; i < nSizeOfIndices; ++i)
{
int nObjIndex = (indices[i] & 0xFF000000) >> 24;
int nVertexIndex = (indices[i] & 0xFFFFFF);
const CKDTree::SStatObj* pObj = &statObjList[nObjIndex];
const IIndexedMesh* pMesh = pObj->pStatObj->GetIndexedMesh();
if (pMesh == nullptr)
{
continue;
}
IIndexedMesh::SMeshDescription meshDesc;
pMesh->GetMeshDescription(meshDesc);
if (meshDesc.m_pVerts)
{
outBestSplitPos += pObj->tm.TransformPoint(meshDesc.m_pVerts[nVertexIndex])[axis];
}
else if (meshDesc.m_pVertsF16)
{
outBestSplitPos += pObj->tm.TransformPoint(meshDesc.m_pVertsF16[nVertexIndex].ToVec3())[axis];
}
}
outBestSplitPos /= nSizeOfIndices;
return true;
}
struct SSplitInfo
{
AABB aboveBoundbox;
std::vector<uint32> aboveIndices;
AABB belowBoundbox;
std::vector<uint32> belowIndices;
};
bool SplitNode(const std::vector<CKDTree::SStatObj>& statObjList, const AABB& boundbox, const std::vector<uint32>& indices, CKDTree::ESplitAxis splitAxis, float splitPos, SSplitInfo& outInfo)
{
if (splitAxis != CKDTree::eSA_X && splitAxis != CKDTree::eSA_Y && splitAxis != CKDTree::eSA_Z)
{
return false;
}
outInfo.aboveBoundbox = boundbox;
outInfo.belowBoundbox = boundbox;
outInfo.aboveBoundbox.max[splitAxis] = splitPos;
outInfo.belowBoundbox.min[splitAxis] = splitPos;
uint32 iIndexSize = (uint32)indices.size();
outInfo.aboveIndices.reserve(iIndexSize);
outInfo.belowIndices.reserve(iIndexSize);
for (uint32 i = 0; i < iIndexSize; ++i)
{
int nObjIndex = (indices[i] & 0xFF000000) >> 24;
int nVertexIndex = indices[i] & 0xFFFFFF;
const CKDTree::SStatObj* pObj = &statObjList[nObjIndex];
const IIndexedMesh* pMesh = pObj->pStatObj->GetIndexedMesh();
if (pMesh == nullptr)
{
return false;
}
IIndexedMesh::SMeshDescription meshDesc;
pMesh->GetMeshDescription(meshDesc);
Vec3 vPos;
if (meshDesc.m_pVerts)
{
vPos = pObj->tm.TransformPoint(meshDesc.m_pVerts[nVertexIndex]);
}
else if (meshDesc.m_pVertsF16)
{
vPos = pObj->tm.TransformPoint(meshDesc.m_pVertsF16[nVertexIndex].ToVec3());
}
else
{
continue;
}
if (vPos[splitAxis] < splitPos)
{
outInfo.aboveIndices.push_back(indices[i]);
assert(outInfo.aboveBoundbox.IsContainPoint(vPos));
}
else
{
outInfo.belowIndices.push_back(indices[i]);
assert(outInfo.belowBoundbox.IsContainPoint(vPos));
}
}
return true;
}
CKDTree::CKDTree()
{
m_pRootNode = nullptr;
}
CKDTree::~CKDTree()
{
if (m_pRootNode)
{
delete m_pRootNode;
}
}
bool CKDTree::Build(IStatObj* pStatObj)
{
if (pStatObj == nullptr)
{
return false;
}
m_StatObjectList.clear();
if (pStatObj->GetIndexedMesh(true))
{
SStatObj rootObj;
rootObj.tm.SetIdentity();
rootObj.pStatObj = pStatObj;
m_StatObjectList.push_back(rootObj);
}
ConstructStatObjList(pStatObj, Matrix34::CreateIdentity());
AABB entireBoundBox;
entireBoundBox.Reset();
std::vector<uint32> indices;
for (int i = 0, iStatObjSize = static_cast<uint32>(m_StatObjectList.size()); i < iStatObjSize; ++i)
{
IIndexedMesh* pMesh = m_StatObjectList[i].pStatObj->GetIndexedMesh(true);
if (pMesh == nullptr)
{
continue;
}
IIndexedMesh::SMeshDescription meshDesc;
pMesh->GetMeshDescription(meshDesc);
for (int k = 0; k < meshDesc.m_nVertCount; ++k)
{
entireBoundBox.Add(m_StatObjectList[i].tm.TransformPoint(meshDesc.m_pVerts[k]));
indices.push_back((i << 24) | k);
}
}
if (m_pRootNode)
{
delete m_pRootNode;
}
m_pRootNode = new KDTreeNode;
BuildRecursively(m_pRootNode, entireBoundBox, indices);
return true;
}
void CKDTree::BuildRecursively(KDTreeNode* pNode, const AABB& boundbox, std::vector<uint32>& indices) const
{
pNode->SetBoundBox(boundbox);
if (indices.size() <= s_MinimumVertexSizeInLeafNode)
{
pNode->SetVertexIndexBuffer(indices);
return;
}
ESplitAxis splitAxis = SearchForBestSplitAxis(boundbox);
float splitPos(0);
SearchForBestSplitPos(splitAxis, m_StatObjectList, indices, splitPos);
pNode->SetSplitAxis(splitAxis);
pNode->SetSplitPos(splitPos);
SSplitInfo splitInfo;
if (!SplitNode(m_StatObjectList, boundbox, indices, splitAxis, splitPos, splitInfo))
{
return;
}
if (splitInfo.aboveIndices.empty() || splitInfo.belowIndices.empty())
{
pNode->SetVertexIndexBuffer(indices);
return;
}
KDTreeNode* pChild0 = new KDTreeNode;
KDTreeNode* pChild1 = new KDTreeNode;
pNode->SetChild(0, pChild0);
pNode->SetChild(1, pChild1);
BuildRecursively(pChild0, splitInfo.aboveBoundbox, splitInfo.aboveIndices);
BuildRecursively(pChild1, splitInfo.belowBoundbox, splitInfo.belowIndices);
}
void CKDTree::ConstructStatObjList(IStatObj* pStatObj, const Matrix34& matParent)
{
if (pStatObj == nullptr)
{
return;
}
for (int i = 0, nChildObjSize(pStatObj->GetSubObjectCount()); i < nChildObjSize; ++i)
{
IStatObj::SSubObject* pSubObj = pStatObj->GetSubObject(i);
SStatObj s;
s.tm = matParent * pSubObj->localTM;
if (pSubObj->pStatObj && pSubObj->pStatObj->GetIndexedMesh(true))
{
s.pStatObj = pSubObj->pStatObj;
m_StatObjectList.push_back(s);
}
ConstructStatObjList(pSubObj->pStatObj, s.tm);
}
}
bool CKDTree::FindNearestVertex(const Vec3& raySrc, const Vec3& rayDir, float vVertexBoxSize, const Vec3& localCameraPos, Vec3& outPos, Vec3& vOutHitPosOnCube) const
{
return FindNearestVertexRecursively(m_pRootNode, raySrc, rayDir, vVertexBoxSize, localCameraPos, outPos, vOutHitPosOnCube);
}
AABB GetNodeBoundBox(KDTreeNode* pNode, float vVertexBoxSize, const Vec3& localCameraPos)
{
AABB nodeAABB = pNode->GetBoundBox();
float fScreenFactorMin = localCameraPos.GetDistance(nodeAABB.min);
Vec3 vBoundBoxMin(fScreenFactorMin * vVertexBoxSize, fScreenFactorMin * vVertexBoxSize, fScreenFactorMin * vVertexBoxSize);
float fScreenFactorMax = localCameraPos.GetDistance(nodeAABB.max);
Vec3 vBoundBoxMax(fScreenFactorMax * vVertexBoxSize, fScreenFactorMax * vVertexBoxSize, fScreenFactorMax * vVertexBoxSize);
nodeAABB.min -= vBoundBoxMin;
nodeAABB.max += vBoundBoxMax;
return nodeAABB;
}
bool CKDTree::FindNearestVertexRecursively(KDTreeNode* pNode, const Vec3& raySrc, const Vec3& rayDir, float vVertexBoxSize, const Vec3& localCameraPos, Vec3& outPos, Vec3& vOutHitPosOnCube) const
{
if (!pNode)
{
return false;
}
Vec3 vHitPos;
AABB nodeAABB = GetNodeBoundBox(pNode, vVertexBoxSize, localCameraPos);
if (!pNode->GetBoundBox().IsContainPoint(raySrc) && !Intersect::Ray_AABB(raySrc, rayDir, nodeAABB, vHitPos))
{
return false;
}
if (pNode->IsLeaf())
{
if (m_StatObjectList.empty())
{
return false;
}
uint32 nVBuffSize = pNode->GetVertexBufferSize();
if (nVBuffSize == 0)
{
return false;
}
float fNearestDist = 3e10f;
for (uint32 i = 0; i < nVBuffSize; ++i)
{
uint32 nVertexIndex = pNode->GetVertexIndex(i);
uint32 nObjIndex = pNode->GetObjIndex(i);
assert(nObjIndex < m_StatObjectList.size());
const SStatObj* pStatObjInfo = &(m_StatObjectList[nObjIndex]);
IIndexedMesh* pMesh = m_StatObjectList[nObjIndex].pStatObj->GetIndexedMesh();
if (pMesh == nullptr)
{
continue;
}
IIndexedMesh::SMeshDescription meshDesc;
pMesh->GetMeshDescription(meshDesc);
Vec3 vCandidatePos(0, 0, 0);
if (meshDesc.m_pVerts)
{
vCandidatePos = pStatObjInfo->tm.TransformPoint(meshDesc.m_pVerts[nVertexIndex]);
}
else if (meshDesc.m_pVertsF16)
{
vCandidatePos = pStatObjInfo->tm.TransformPoint(meshDesc.m_pVertsF16[nVertexIndex].ToVec3());
}
else
{
continue;
}
float fScreenFactor = localCameraPos.GetDistance(vCandidatePos);
Vec3 vBoundBox(fScreenFactor * vVertexBoxSize, fScreenFactor * vVertexBoxSize, fScreenFactor * vVertexBoxSize);
Vec3 vHitPosOnCube;
if (Intersect::Ray_AABB(raySrc, rayDir, AABB(vCandidatePos - vBoundBox, vCandidatePos + vBoundBox), vHitPosOnCube))
{
float fDist = vHitPosOnCube.GetDistance(raySrc);
if (fDist < fNearestDist)
{
fNearestDist = fDist;
outPos = vCandidatePos;
vOutHitPosOnCube = vHitPosOnCube;
}
}
}
if (fNearestDist < 3e10f)
{
return true;
}
return false;
}
Vec3 vNearestPos0, vNearestPos0OnCube;
Vec3 vNearestPos1, vNearestPos1OnCube;
bool bFoundChild0 = FindNearestVertexRecursively(pNode->GetChild(0), raySrc, rayDir, vVertexBoxSize, localCameraPos, vNearestPos0, vNearestPos0OnCube);
bool bFoundChild1 = FindNearestVertexRecursively(pNode->GetChild(1), raySrc, rayDir, vVertexBoxSize, localCameraPos, vNearestPos1, vNearestPos1OnCube);
if (bFoundChild0 && bFoundChild1)
{
float fDist0 = raySrc.GetDistance(vNearestPos0OnCube);
float fDist1 = raySrc.GetDistance(vNearestPos1OnCube);
if (fDist0 < fDist1)
{
outPos = vNearestPos0;
vOutHitPosOnCube = vNearestPos0OnCube;
}
else
{
outPos = vNearestPos1;
vOutHitPosOnCube = vNearestPos1OnCube;
}
}
else if (bFoundChild0 && !bFoundChild1)
{
outPos = vNearestPos0;
vOutHitPosOnCube = vNearestPos0OnCube;
}
else if (!bFoundChild0 && bFoundChild1)
{
outPos = vNearestPos1;
vOutHitPosOnCube = vNearestPos1OnCube;
}
return bFoundChild0 || bFoundChild1;
}
void CKDTree::GetPenetratedBoxes(const Vec3& raySrc, const Vec3& rayDir, std::vector<AABB>& outBoxes)
{
GetPenetratedBoxesRecursively(m_pRootNode, raySrc, rayDir, outBoxes);
}
void CKDTree::GetPenetratedBoxesRecursively(KDTreeNode* pNode, const Vec3& raySrc, const Vec3& rayDir, std::vector<AABB>& outBoxes)
{
Vec3 vHitPos;
if (!pNode || (!pNode->GetBoundBox().IsContainPoint(raySrc) && !Intersect::Ray_AABB(raySrc, rayDir, pNode->GetBoundBox(), vHitPos)))
{
return;
}
outBoxes.push_back(pNode->GetBoundBox());
GetPenetratedBoxesRecursively(pNode->GetChild(0), raySrc, rayDir, outBoxes);
GetPenetratedBoxesRecursively(pNode->GetChild(1), raySrc, rayDir, outBoxes);
}
-57
View File
@@ -1,57 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_EDITOR_UTIL_KDTREE_H
#define CRYINCLUDE_EDITOR_UTIL_KDTREE_H
#pragma once
struct IStatObj;
class KDTreeNode;
class CKDTree
{
public:
CKDTree();
~CKDTree();
bool Build(IStatObj* pStatObj);
bool FindNearestVertex(const Vec3& raySrc, const Vec3& rayDir, float vVertexBoxSize, const Vec3& localCameraPos, Vec3& outPos, Vec3& vOutHitPosOnCube) const;
void GetPenetratedBoxes(const Vec3& raySrc, const Vec3& rayDir, std::vector<AABB>& outBoxes);
enum ESplitAxis
{
eSA_X = 0,
eSA_Y,
eSA_Z,
eSA_Invalid
};
struct SStatObj
{
Matrix34 tm;
IStatObj* pStatObj;
};
private:
void BuildRecursively(KDTreeNode* pNode, const AABB& boundbox, std::vector<uint32>& indices) const;
bool FindNearestVertexRecursively(KDTreeNode* pNode, const Vec3& raySrc, const Vec3& rayDir, float vVertexBoxSize, const Vec3& localCameraPos, Vec3& outPos, Vec3& vOutHitPosOnCube) const;
void GetPenetratedBoxesRecursively(KDTreeNode* pNode, const Vec3& raySrc, const Vec3& rayDir, std::vector<AABB>& outBoxes);
void ConstructStatObjList(IStatObj* pStatObj, const Matrix34& matParent);
static const int s_MinimumVertexSizeInLeafNode = 4;
private:
KDTreeNode* m_pRootNode;
std::vector<SStatObj> m_StatObjectList;
};
#endif // CRYINCLUDE_EDITOR_UTIL_KDTREE_H
-96
View File
@@ -16,102 +16,6 @@
//////////////////////////////////////////////////////////////////////////
// CXmlArchive
bool CXmlArchive::Load(const QString& file)
{
bLoading = true;
char filename[AZ_MAX_PATH_LEN] = { 0 };
AZ::IO::FileIOBase::GetInstance()->ResolvePath(file.toUtf8().data(), filename, AZ_MAX_PATH_LEN);
QFile cFile(filename);
if (!cFile.open(QFile::ReadOnly))
{
CLogFile::FormatLine("Warning: Loading of %s failed", filename);
return false;
}
CArchive ar(&cFile, CArchive::load);
QString str;
ar >> str;
root = XmlHelpers::LoadXmlFromBuffer(str.toUtf8().data(), str.toUtf8().length());
if (!root)
{
// If we didn't extract valid XML, attempt to check the header to see if we're dealing with an improperly serialized archive
// When deserializing QStrings, we use readStringLength in EditorUtils, which mimics MFC's decoding.
// In this encoding, the length is first read as an unsigned 8-bit value, if that is 0xFF then the next two bytes are read
// If the 16 bit uint is 0xFFFF, then the next four bytes are read, etc. up to a final 64 bit value.
// In 1.09, there was a bug in which we'd serialize out the 32-bit length improperly like so:
// 0xFF 0xFF 0x00 <4 byte proper length>
// Note that the header could also historically start with 0xFF 0xFF 0xFE to indicate wide strings prior to the length data
// but we don't have to deal with that here as the broken version of the code never prepended this
cFile.seek(0);
quint8 len8;
ar >> len8;
quint16 len16;
ar >> len16;
// Possible bad header, attempt to read 32 bit length.
if (len8 == 0xff && len16 == 0xff)
{
// This version of operator<< only serialized out UTF8 strings up to 32 bits of length, no need to 64-bit check or do wchar.
quint32 len32;
ar >> len32;
str = QString::fromUtf8(cFile.read(len32));
root = XmlHelpers::LoadXmlFromBuffer(str.toUtf8().data(), str.toUtf8().length());
}
if (!root)
{
CLogFile::FormatLine("Warning: Loading of %s failed", filename);
return false;
}
}
const bool loaded = pNamedData->Serialize(ar);
if (!loaded)
{
CLogFile::FormatLine("Error: Can't load xml file: '%s'! File corrupted. Binary file possibly was corrupted by Source Control if it was marked like text format.", filename);
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
void CXmlArchive::Save(const QString& file)
{
char filename[AZ_MAX_PATH_LEN] = { 0 };
AZ::IO::FileIOBase::GetInstance()->ResolvePath(file.toUtf8().data(), filename, AZ_MAX_PATH_LEN);
bLoading = false;
if (!root)
{
return;
}
QFile cFile(filename);
// Open the file for writing, create it if needed
if (!cFile.open(QFile::WriteOnly))
{
CLogFile::FormatLine("Warning: Saving of %s failed", filename);
return;
}
// Create the archive object
CArchive ar(&cFile, CArchive::store);
_smart_ptr<IXmlStringData> pXmlStrData = root->getXMLData(5000000);
// Need convert to QString for CArchive::operator<<
QString str = pXmlStrData->GetString();
ar << str;
pNamedData->Serialize(ar);
}
//////////////////////////////////////////////////////////////////////////
bool CXmlArchive::SaveToPak([[maybe_unused]] const QString& levelPath, CPakFile& pakFile)
-3
View File
@@ -60,9 +60,6 @@ public:
return *this;
}
bool Load(const QString& file);
void Save(const QString& file);
//! Save XML Archive to pak file.
//! @return true if saved.
bool SaveToPak(const QString& levelPath, CPakFile& pakFile);