Merge branch 'main' of https://github.com/aws-lumberyard/o3de into ly-as-sdk/LYN-2948-phistere
This commit is contained in:
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_ARRAY2D_H
|
||||
#define CRYINCLUDE_CRYCOMMON_ARRAY2D_H
|
||||
#pragma once
|
||||
|
||||
// Dynamic replacement for static 2d array
|
||||
template <class T>
|
||||
struct Array2d
|
||||
{
|
||||
Array2d()
|
||||
{
|
||||
m_nSize = 0;
|
||||
m_pData = 0;
|
||||
}
|
||||
|
||||
int GetSize() const { return m_nSize; }
|
||||
int GetDataSize() const { return m_nSize * m_nSize * sizeof(T); }
|
||||
|
||||
T* GetData() { return m_pData; }
|
||||
|
||||
T* GetDataEnd() { return &m_pData[m_nSize * m_nSize]; }
|
||||
|
||||
void SetData(T* pData, int nSize)
|
||||
{
|
||||
Allocate(nSize);
|
||||
memcpy(m_pData, pData, nSize * nSize * sizeof(T));
|
||||
}
|
||||
|
||||
void Allocate(int nSize)
|
||||
{
|
||||
if (m_nSize == nSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
delete [] m_pData;
|
||||
|
||||
m_nSize = nSize;
|
||||
m_pData = new T [nSize * nSize];
|
||||
memset(m_pData, 0, nSize * nSize * sizeof(T));
|
||||
}
|
||||
|
||||
~Array2d()
|
||||
{
|
||||
delete [] m_pData;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
delete [] m_pData;
|
||||
m_pData = 0;
|
||||
m_nSize = 0;
|
||||
}
|
||||
|
||||
T* m_pData;
|
||||
int m_nSize;
|
||||
|
||||
T* operator [] (const int& nPos) const
|
||||
{
|
||||
assert(nPos >= 0 && nPos < m_nSize);
|
||||
return &m_pData[nPos * m_nSize];
|
||||
}
|
||||
|
||||
Array2d& operator = (const Array2d& other)
|
||||
{
|
||||
Allocate(other.m_nSize);
|
||||
memcpy(m_pData, other.m_pData, m_nSize * m_nSize * sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_ARRAY2D_H
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
// Description: Utilities and functions used when cryphysics is disabled
|
||||
|
||||
#pragma once
|
||||
|
||||
// Assert if CryPhysics is disabled and no functionality replacement has been implemented
|
||||
// 1: Runtime AZ_Error
|
||||
// 2: Runtime Assertion
|
||||
// 3: Compilation error
|
||||
// Other: Do nothing
|
||||
#define ENABLE_CRY_PHYSICS_REPLACEMENT_ASSERT 0
|
||||
|
||||
#if (ENABLE_CRY_PHYSICS_REPLACEMENT_ASSERT == 1)
|
||||
#define CRY_PHYSICS_REPLACEMENT_ASSERT() AZ_Error("CryPhysics", false, __FUNCTION__ " - CRYPHYSICS REPLACEMENT NOT IMPLEMENTED")
|
||||
#elif (ENABLE_CRY_PHYSICS_REPLACEMENT_ASSERT == 2)
|
||||
#define CRY_PHYSICS_REPLACEMENT_ASSERT() AZ_Assert(false, "CRYPHYSICS REPLACEMENT NOT IMPLEMENTED")
|
||||
#elif (ENABLE_CRY_PHYSICS_REPLACEMENT_ASSERT == 3)
|
||||
#define CRY_PHYSICS_REPLACEMENT_ASSERT() static_assert(false, __FUNCTION__ " - CRYPHYSICS REPLACEMENT NOT IMPLEMENTED")
|
||||
#else
|
||||
#define CRY_PHYSICS_REPLACEMENT_ASSERT()
|
||||
#endif
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_CRYPTRARRAY_H
|
||||
#define CRYINCLUDE_CRYCOMMON_CRYPTRARRAY_H
|
||||
#pragma once
|
||||
|
||||
#include "CryArray.h"
|
||||
#include "CrySizer.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T, class P = T*>
|
||||
struct PtrArray
|
||||
: DynArray<P>
|
||||
{
|
||||
typedef DynArray<P> super;
|
||||
|
||||
// Overrides.
|
||||
typedef T value_type;
|
||||
|
||||
ILINE ~PtrArray(){}
|
||||
|
||||
inline T& operator [](int i) const
|
||||
{ return *super::operator[](i); }
|
||||
|
||||
// Iterators.
|
||||
struct iterator
|
||||
{
|
||||
iterator(P* p)
|
||||
: _ptr(p)
|
||||
{}
|
||||
|
||||
operator P* () const
|
||||
{
|
||||
return _ptr;
|
||||
}
|
||||
void operator++()
|
||||
{ _ptr++; }
|
||||
void operator--()
|
||||
{ _ptr--; }
|
||||
T& operator*() const
|
||||
{ assert(_ptr); return **_ptr; }
|
||||
T* operator->() const
|
||||
{ assert(_ptr); return *_ptr; }
|
||||
|
||||
protected:
|
||||
P* _ptr;
|
||||
};
|
||||
|
||||
struct const_iterator
|
||||
{
|
||||
const_iterator(const P* p)
|
||||
: _ptr(p)
|
||||
{}
|
||||
|
||||
operator const P* () const
|
||||
{
|
||||
return _ptr;
|
||||
}
|
||||
void operator++()
|
||||
{ _ptr++; }
|
||||
void operator--()
|
||||
{ _ptr--; }
|
||||
T& operator*() const
|
||||
{ assert(_ptr); return **_ptr; }
|
||||
T* operator->() const
|
||||
{ assert(_ptr); return *_ptr; }
|
||||
|
||||
protected:
|
||||
const P* _ptr;
|
||||
};
|
||||
|
||||
void GetMemoryUsage(ICrySizer* pSizer) const
|
||||
{
|
||||
pSizer->AddObject(this->begin(), this->get_alloc_size());
|
||||
for (int i = 0; i < this->size(); ++i)
|
||||
{
|
||||
pSizer->AddObject(this->super::operator [](i));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
struct SmartPtrArray
|
||||
: PtrArray< T, _smart_ptr<T> >
|
||||
{
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_CRYPTRARRAY_H
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <Cry_Vector3.h>
|
||||
#include <Cry_Quat.h>
|
||||
#include <Cry_Color.h>
|
||||
#include <CryArray2d.h>
|
||||
#include <smartptr.h>
|
||||
|
||||
// forward declarations for overloads
|
||||
@@ -249,12 +248,6 @@ public:
|
||||
void AddObject([[maybe_unused]] const AZ::Vector3& rObj) {}
|
||||
void AddObject(void*) {}
|
||||
|
||||
template<typename T>
|
||||
void AddObject(const Array2d<T>& array2d)
|
||||
{
|
||||
this->AddObject(array2d.m_pData, array2d.GetDataSize());
|
||||
}
|
||||
|
||||
// overloads for container, will automaticly traverse the content
|
||||
template<typename T, typename Alloc>
|
||||
void AddObject(const std::list<T, Alloc>& rList)
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef> // size_t
|
||||
|
||||
namespace Detail
|
||||
{
|
||||
template <typename T, size_t size>
|
||||
char (&ArrayCountHelper(T(&)[size]))[size];
|
||||
}
|
||||
|
||||
#define CRY_ARRAY_COUNT(arr) sizeof(::Detail::ArrayCountHelper(arr))
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Include this file instead of including zlib.h directly
|
||||
// because zconf.h (included by zlib.h) defines WINDOWS and WIN32 - those
|
||||
// definitions conflict with CryEngine's definitions.
|
||||
|
||||
#if defined(CRY_TMP_DEFINED_WINDOWS) || defined(CRY_TMP_DEFINED_WIN32)
|
||||
# error CRY_TMP_DEFINED_WINDOWS and/or CRY_TMP_DEFINED_WIN32 already defined
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS)
|
||||
# define CRY_TMP_DEFINED_WINDOWS 1
|
||||
#endif
|
||||
#if defined(WIN32)
|
||||
# define CRY_TMP_DEFINED_WIN32 1
|
||||
#endif
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#if !defined(CRY_TMP_DEFINED_WINDOWS)
|
||||
# undef WINDOWS
|
||||
#endif
|
||||
#undef CRY_TMP_DEFINED_WINDOWS
|
||||
#if !defined(CRY_TMP_DEFINED_WIN32)
|
||||
# undef WIN32
|
||||
#endif
|
||||
#undef CRY_TMP_DEFINED_WIN32
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,469 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Facility for efficiently generating random positions on geometry
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_GEOMQUERY_H
|
||||
#define CRYINCLUDE_CRYCOMMON_GEOMQUERY_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Cry_Geo.h"
|
||||
#include "CryArray.h"
|
||||
#include "Random.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Extents cache
|
||||
|
||||
class CGeomExtent
|
||||
{
|
||||
public:
|
||||
|
||||
CGeomExtent()
|
||||
: m_nEmptyEndParts(0) {}
|
||||
|
||||
ILINE operator bool() const
|
||||
{
|
||||
return m_afCumExtents.capacity() + m_nEmptyEndParts != 0;
|
||||
}
|
||||
ILINE int NumParts() const
|
||||
{
|
||||
return m_afCumExtents.size();
|
||||
}
|
||||
ILINE float TotalExtent() const
|
||||
{
|
||||
return !m_afCumExtents.empty() ? m_afCumExtents.back() : 0.f;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
m_afCumExtents.clear();
|
||||
m_nEmptyEndParts = 0;
|
||||
}
|
||||
void AddPart(float fExtent)
|
||||
{
|
||||
// Defer empty parts until a non-empty part is added.
|
||||
if (fExtent <= 0.f)
|
||||
{
|
||||
m_nEmptyEndParts++;
|
||||
}
|
||||
else
|
||||
{
|
||||
float fTotal = TotalExtent();
|
||||
for (; m_nEmptyEndParts; m_nEmptyEndParts--)
|
||||
{
|
||||
m_afCumExtents.push_back(fTotal);
|
||||
}
|
||||
m_afCumExtents.push_back(fTotal + fExtent);
|
||||
}
|
||||
}
|
||||
void ReserveParts(int nCount)
|
||||
{
|
||||
m_afCumExtents.reserve(nCount);
|
||||
}
|
||||
|
||||
// Find element in sorted array <= index (normalized 0 to 1)
|
||||
int GetPart(float fIndex) const
|
||||
{
|
||||
int last = m_afCumExtents.size() - 1;
|
||||
if (last <= 0)
|
||||
{
|
||||
return last;
|
||||
}
|
||||
|
||||
fIndex *= m_afCumExtents[last];
|
||||
|
||||
// Binary search thru array.
|
||||
int lo = 0, hi = last;
|
||||
while (lo < hi)
|
||||
{
|
||||
int i = (lo + hi) >> 1;
|
||||
if (fIndex < m_afCumExtents[i])
|
||||
{
|
||||
hi = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
lo = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
assert(lo == 0 || m_afCumExtents[lo] > m_afCumExtents[lo - 1]);
|
||||
return lo;
|
||||
}
|
||||
|
||||
int RandomPart() const
|
||||
{
|
||||
return GetPart(cry_random(0.0f, 1.0f));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
DynArray<float> m_afCumExtents;
|
||||
int m_nEmptyEndParts;
|
||||
};
|
||||
|
||||
class CGeomExtents
|
||||
{
|
||||
public:
|
||||
|
||||
ILINE CGeomExtents()
|
||||
: m_aExtents(0) {}
|
||||
~CGeomExtents()
|
||||
{ delete[] m_aExtents; }
|
||||
|
||||
void Clear()
|
||||
{
|
||||
delete[] m_aExtents;
|
||||
m_aExtents = 0;
|
||||
}
|
||||
|
||||
ILINE CGeomExtent const& operator [](EGeomForm eForm) const
|
||||
{
|
||||
assert(eForm >= 0 && eForm < MaxGeomForm);
|
||||
if (m_aExtents)
|
||||
{
|
||||
return m_aExtents[eForm];
|
||||
}
|
||||
|
||||
static CGeomExtent s_empty;
|
||||
return s_empty;
|
||||
}
|
||||
|
||||
ILINE CGeomExtent& Make(EGeomForm eForm)
|
||||
{
|
||||
assert(eForm >= 0 && eForm < MaxGeomForm);
|
||||
if (!m_aExtents)
|
||||
{
|
||||
m_aExtents = new CGeomExtent[4];
|
||||
}
|
||||
return m_aExtents[eForm];
|
||||
}
|
||||
|
||||
protected:
|
||||
CGeomExtent* m_aExtents;
|
||||
};
|
||||
|
||||
|
||||
// Other random/extent functions
|
||||
|
||||
inline float ScaleExtent(EGeomForm eForm, float fScale)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
return 1;
|
||||
case GeomForm_Edges:
|
||||
return fScale;
|
||||
case GeomForm_Surface:
|
||||
return fScale * fScale;
|
||||
case GeomForm_Volume:
|
||||
return fScale * fScale * fScale;
|
||||
}
|
||||
}
|
||||
|
||||
inline float BoxExtent(EGeomForm eForm, Vec3 const& vSize)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Vertices:
|
||||
return 8.f;
|
||||
case GeomForm_Edges:
|
||||
return (vSize.x + vSize.y + vSize.z) * 8.f;
|
||||
case GeomForm_Surface:
|
||||
return (vSize.x * vSize.y + vSize.x * vSize.z + vSize.y * vSize.z) * 8.f;
|
||||
case GeomForm_Volume:
|
||||
return vSize.x * vSize.y * vSize.z * 8.f;
|
||||
}
|
||||
}
|
||||
|
||||
// Utility functions.
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const typename T::value_type& RandomElem(const T& array)
|
||||
{
|
||||
int n = cry_random(0U, array.size() - 1);
|
||||
return array[n];
|
||||
}
|
||||
|
||||
// Geometric primitive randomizing functions.
|
||||
ILINE void BoxRandomPos(PosNorm& ran, EGeomForm eForm, Vec3 const& vSize)
|
||||
{
|
||||
ran.vPos = cry_random_componentwise(-vSize, vSize);
|
||||
ran.vNorm = ran.vPos;
|
||||
|
||||
if (eForm != GeomForm_Volume)
|
||||
{
|
||||
// Generate a random corner, for collapsing random point.
|
||||
int nCorner = cry_random(0, 7);
|
||||
ran.vNorm.x = (((nCorner & 1) << 1) - 1) * vSize.x;
|
||||
ran.vNorm.y = (((nCorner & 2)) - 1) * vSize.y;
|
||||
ran.vNorm.z = (((nCorner & 4) >> 1) - 1) * vSize.z;
|
||||
|
||||
if (eForm == GeomForm_Vertices)
|
||||
{
|
||||
ran.vPos = ran.vNorm;
|
||||
}
|
||||
else if (eForm == GeomForm_Surface)
|
||||
{
|
||||
// Collapse one axis.
|
||||
float fAxis = cry_random(0.0f, vSize.x * vSize.y + vSize.y * vSize.z + vSize.z * vSize.x);
|
||||
if ((fAxis -= vSize.y * vSize.z) < 0.f)
|
||||
{
|
||||
ran.vPos.x = ran.vNorm.x;
|
||||
ran.vNorm.y = ran.vNorm.z = 0.f;
|
||||
}
|
||||
else if ((fAxis -= vSize.z * vSize.x) < 0.f)
|
||||
{
|
||||
ran.vPos.y = ran.vNorm.y;
|
||||
ran.vNorm.x = ran.vNorm.z = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
ran.vPos.z = ran.vNorm.z;
|
||||
ran.vNorm.x = ran.vNorm.y = 0.f;
|
||||
}
|
||||
}
|
||||
else if (eForm == GeomForm_Edges)
|
||||
{
|
||||
// Collapse 2 axes.
|
||||
float fAxis = cry_random(0.0f, vSize.x + vSize.y + vSize.z);
|
||||
if ((fAxis -= vSize.x) < 0.f)
|
||||
{
|
||||
ran.vPos.y = ran.vNorm.y;
|
||||
ran.vPos.z = ran.vNorm.z;
|
||||
ran.vNorm.x = 0.f;
|
||||
}
|
||||
else if ((fAxis -= vSize.y) < 0.f)
|
||||
{
|
||||
ran.vPos.x = ran.vNorm.x;
|
||||
ran.vPos.z = ran.vNorm.z;
|
||||
ran.vNorm.y = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
ran.vPos.x = ran.vNorm.x;
|
||||
ran.vPos.y = ran.vNorm.y;
|
||||
ran.vNorm.z = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ran.vNorm.Normalize();
|
||||
}
|
||||
|
||||
inline float CircleExtent(EGeomForm eForm, float fRadius)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
case GeomForm_Edges:
|
||||
return gf_PI2 * fRadius;
|
||||
case GeomForm_Surface:
|
||||
return gf_PI * square(fRadius);
|
||||
default:
|
||||
return 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
inline Vec2 CircleRandomPoint(EGeomForm eForm, float fRadius)
|
||||
{
|
||||
Vec2 vPt;
|
||||
switch (eForm)
|
||||
{
|
||||
case GeomForm_Edges:
|
||||
// Generate random angle.
|
||||
sincos_tpl(cry_random(0.0f, gf_PI2), &vPt.y, &vPt.x);
|
||||
vPt *= fRadius;
|
||||
break;
|
||||
case GeomForm_Surface:
|
||||
// Generate random angle, and radius, adjusted for even distribution.
|
||||
sincos_tpl(cry_random(0.0f, gf_PI2), &vPt.y, &vPt.x);
|
||||
vPt *= sqrt(cry_random(0.0f, 1.0f)) * fRadius;
|
||||
break;
|
||||
default:
|
||||
vPt.x = vPt.y = 0.f;
|
||||
}
|
||||
return vPt;
|
||||
}
|
||||
|
||||
inline float SphereExtent(EGeomForm eForm, float fRadius)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Vertices:
|
||||
case GeomForm_Edges:
|
||||
return 0.f;
|
||||
case GeomForm_Surface:
|
||||
return gf_PI * 4.f * sqr(fRadius);
|
||||
case GeomForm_Volume:
|
||||
return gf_PI * 4.f / 3.f * cube(fRadius);
|
||||
}
|
||||
}
|
||||
|
||||
inline void SphereRandomPos(PosNorm& ran, EGeomForm eForm, float fRadius)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Vertices:
|
||||
case GeomForm_Edges:
|
||||
ran.vPos.zero();
|
||||
ran.vNorm.zero();
|
||||
return;
|
||||
case GeomForm_Surface:
|
||||
case GeomForm_Volume:
|
||||
{
|
||||
// Generate point on surface, as normal.
|
||||
float fPhi = cry_random(0.0f, gf_PI2);
|
||||
float fZ = cry_random(-1.f, 1.f);
|
||||
float fH = sqrt_tpl(1.f - fZ * fZ);
|
||||
sincos_tpl(fPhi, &ran.vNorm.y, &ran.vNorm.x);
|
||||
ran.vNorm.x *= fH;
|
||||
ran.vNorm.y *= fH;
|
||||
ran.vNorm.z = fZ;
|
||||
|
||||
ran.vPos = ran.vNorm;
|
||||
if (eForm == GeomForm_Volume)
|
||||
{
|
||||
float fV = cry_random(0.0f, 1.0f);
|
||||
float fR = pow_tpl(fV, 0.333333f);
|
||||
ran.vPos *= fR;
|
||||
}
|
||||
ran.vPos *= fRadius;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Triangle randomisation functions
|
||||
|
||||
inline float TriExtent(EGeomForm eForm, Vec3 const aPos[3])
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Edges:
|
||||
return (aPos[1] - aPos[0]).GetLengthFast();
|
||||
case GeomForm_Surface:
|
||||
return ((aPos[1] - aPos[0]) % (aPos[2] - aPos[0])).GetLengthFast() * 0.5f;
|
||||
case GeomForm_Volume:
|
||||
// Generate signed volume of pyramid by computing triple product of vertices.
|
||||
return ((aPos[0] ^ aPos[1]) | aPos[2]) / 6.0f;
|
||||
}
|
||||
}
|
||||
|
||||
inline void TriRandomPos(PosNorm& ran, EGeomForm eForm, PosNorm const aRan[3], bool bDoNormals)
|
||||
{
|
||||
// Generate interpolators for verts.
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Vertices:
|
||||
ran = aRan[0];
|
||||
return;
|
||||
case GeomForm_Edges:
|
||||
{
|
||||
float t = cry_random(0.0f, 1.0f);
|
||||
ran.vPos = aRan[0].vPos * (1.f - t) + aRan[1].vPos * t;
|
||||
if (bDoNormals)
|
||||
{
|
||||
ran.vNorm = aRan[0].vNorm * (1.f - t) + aRan[1].vNorm * t;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeomForm_Surface:
|
||||
{
|
||||
float t0 = cry_random(0.0f, 1.0f);
|
||||
float t1 = cry_random(0.0f, 1.0f);
|
||||
float t2 = cry_random(0.0f, 1.0f);
|
||||
float fSum = t0 + t1 + t2;
|
||||
ran.vPos = (aRan[0].vPos * t0 + aRan[1].vPos * t1 + aRan[2].vPos * t2) * (1.f / fSum);
|
||||
if (bDoNormals)
|
||||
{
|
||||
ran.vNorm = aRan[0].vNorm * t0 + aRan[1].vNorm * t1 + aRan[2].vNorm * t2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeomForm_Volume:
|
||||
{
|
||||
float t0 = cry_random(0.0f, 1.0f);
|
||||
float t1 = cry_random(0.0f, 1.0f);
|
||||
float t2 = cry_random(0.0f, 1.0f);
|
||||
float t3 = cry_random(0.0f, 1.0f);
|
||||
float fSum = t0 + t1 + t2 + t3;
|
||||
ran.vPos = (aRan[0].vPos * t0 + aRan[1].vPos * t1 + aRan[2].vPos * t2) * (1.f / fSum);
|
||||
if (bDoNormals)
|
||||
{
|
||||
ran.vNorm = (aRan[0].vNorm * t0 + aRan[1].vNorm * t1 + aRan[2].vNorm * t2) * (1.f - t3) + ran.vPos.GetNormalizedFast() * t3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bDoNormals)
|
||||
{
|
||||
ran.vNorm.Normalize();
|
||||
}
|
||||
}
|
||||
|
||||
// Mesh random pos functions
|
||||
|
||||
inline int TriMeshPartCount(EGeomForm eForm, int nIndices)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Vertices:
|
||||
case GeomForm_Edges:
|
||||
// Number of edges = verts.
|
||||
return nIndices;
|
||||
case GeomForm_Surface:
|
||||
case GeomForm_Volume:
|
||||
// Number of tris.
|
||||
assert(nIndices % 3 == 0);
|
||||
return nIndices / 3;
|
||||
}
|
||||
}
|
||||
|
||||
inline int TriIndices(int aIndices[3], int nPart, EGeomForm eForm)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Vertices: // Part is vert index
|
||||
aIndices[0] = nPart;
|
||||
return 1;
|
||||
case GeomForm_Edges: // Part is vert index
|
||||
aIndices[0] = nPart;
|
||||
aIndices[1] = nPart % 3 < 2 ? nPart + 1 : nPart - 2;
|
||||
return 2;
|
||||
case GeomForm_Surface: // Part is tri index
|
||||
case GeomForm_Volume:
|
||||
aIndices[0] = nPart * 3;
|
||||
aIndices[1] = aIndices[0] + 1;
|
||||
aIndices[2] = aIndices[0] + 2;
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_GEOMQUERY_H
|
||||
@@ -1,617 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_HASHGRID_H
|
||||
#define CRYINCLUDE_CRYCOMMON_HASHGRID_H
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
template<typename Key, typename DiscreetKey>
|
||||
struct hash_grid_2d
|
||||
{
|
||||
typedef Key key_type;
|
||||
typedef typename key_type::value_type key_value;
|
||||
|
||||
typedef DiscreetKey discreet_type;
|
||||
typedef typename discreet_type::value_type discreet_value;
|
||||
|
||||
typedef hash_grid_2d<Key, DiscreetKey> type;
|
||||
|
||||
hash_grid_2d(const key_value& cellSizeX, const key_value& cellSizeY, const key_value& cellSizeZ)
|
||||
: scaleFactorX(1 / cellSizeX)
|
||||
, scaleFactorY(1 / cellSizeY)
|
||||
{
|
||||
}
|
||||
|
||||
inline discreet_type discreet(const key_type& key) const
|
||||
{
|
||||
return discreet_type(static_cast<discreet_value>(key[0] * scaleFactorX),
|
||||
static_cast<discreet_value>(key[1] * scaleFactorY),
|
||||
static_cast<discreet_value>(0));
|
||||
}
|
||||
|
||||
inline size_t hash(const key_type& key) const
|
||||
{
|
||||
return hash(discreet(key));
|
||||
}
|
||||
|
||||
inline size_t hash(const discreet_type& discreet) const
|
||||
{
|
||||
return static_cast<size_t>(
|
||||
(discreet[0] ^ 920129341) +
|
||||
(discreet[1] ^ 1926129311));
|
||||
}
|
||||
|
||||
inline void swap(type& other)
|
||||
{
|
||||
std::swap(scaleFactorX, other.scaleFactorX);
|
||||
std::swap(scaleFactorY, other.scaleFactorY);
|
||||
}
|
||||
|
||||
private:
|
||||
key_value scaleFactorX;
|
||||
key_value scaleFactorY;
|
||||
};
|
||||
|
||||
|
||||
template<typename Key, typename DiscreetKey>
|
||||
struct hash_grid_3d
|
||||
{
|
||||
typedef Key key_type;
|
||||
typedef typename key_type::value_type key_value;
|
||||
|
||||
typedef DiscreetKey discreet_type;
|
||||
typedef typename discreet_type::value_type discreet_value;
|
||||
|
||||
typedef hash_grid_3d<Key, DiscreetKey> type;
|
||||
|
||||
hash_grid_3d(const key_value& cellSizeX, const key_value& cellSizeY, const key_value& cellSizeZ)
|
||||
: scaleFactorX(1 / cellSizeX)
|
||||
, scaleFactorY(1 / cellSizeY)
|
||||
, scaleFactorZ(1 / cellSizeZ)
|
||||
{
|
||||
}
|
||||
|
||||
inline discreet_type discreet(const key_type& key) const
|
||||
{
|
||||
return discreet_type(static_cast<discreet_value>(key[0] * scaleFactorX),
|
||||
static_cast<discreet_value>(key[1] * scaleFactorY),
|
||||
static_cast<discreet_value>(key[2] * scaleFactorZ));
|
||||
}
|
||||
|
||||
inline size_t hash(const key_type& key) const
|
||||
{
|
||||
return hash(discreet(key));
|
||||
}
|
||||
|
||||
inline size_t hash(const discreet_type& discreet) const
|
||||
{
|
||||
return static_cast<size_t>(
|
||||
(discreet[0] ^ 920129341ul) +
|
||||
(discreet[1] ^ 1926129311ul) +
|
||||
(discreet[2] ^ 3926129401ul));
|
||||
}
|
||||
|
||||
inline void swap(type& other)
|
||||
{
|
||||
std::swap(scaleFactorX, other.scaleFactorX);
|
||||
std::swap(scaleFactorY, other.scaleFactorY);
|
||||
std::swap(scaleFactorZ, other.scaleFactorZ);
|
||||
}
|
||||
|
||||
private:
|
||||
key_value scaleFactorX;
|
||||
key_value scaleFactorY;
|
||||
key_value scaleFactorZ;
|
||||
};
|
||||
|
||||
|
||||
template<typename KeyType, typename ValueType>
|
||||
struct hash_grid_no_position
|
||||
{
|
||||
KeyType operator()(const ValueType&) const
|
||||
{
|
||||
switch (0)
|
||||
{
|
||||
case 0:
|
||||
"hash_grid query performed without a valid position-retriever implementation";
|
||||
}
|
||||
;
|
||||
|
||||
return KeyType();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<int NumberOfCells, typename ValueType, typename KeyHash,
|
||||
typename PositionRetriever = hash_grid_no_position<typename KeyHash::key_type, ValueType> >
|
||||
class hash_grid
|
||||
: protected KeyHash
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
CellCount = NumberOfCells,
|
||||
};
|
||||
|
||||
typedef ValueType value_type;
|
||||
typedef KeyHash key_hash;
|
||||
|
||||
typedef typename key_hash::key_type key_type;
|
||||
typedef typename key_type::value_type key_value;
|
||||
typedef typename key_hash::discreet_type discreet_type;
|
||||
typedef typename discreet_type::value_type discreet_value;
|
||||
|
||||
|
||||
typedef PositionRetriever position_retriever_type;
|
||||
|
||||
typedef hash_grid<NumberOfCells, ValueType, KeyHash, PositionRetriever> type;
|
||||
|
||||
typedef std::vector<value_type> items_type;
|
||||
|
||||
struct cell_type
|
||||
{
|
||||
cell_type()
|
||||
: query(0)
|
||||
{
|
||||
}
|
||||
|
||||
mutable uint32 query;
|
||||
items_type items;
|
||||
};
|
||||
typedef std::vector<cell_type> cells_type;
|
||||
|
||||
inline hash_grid(float cellSizeX = 20.0f, float cellSizeY = 20.0f, float cellSizeZ = 20.0f,
|
||||
const position_retriever_type& _position = position_retriever_type())
|
||||
: key_hash(cellSizeX, cellSizeY, cellSizeZ)
|
||||
, position(_position)
|
||||
, m_cells(CellCount)
|
||||
, m_count(0)
|
||||
, m_query(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
m_cells.clear();
|
||||
m_cells.resize(CellCount);
|
||||
m_count = 0;
|
||||
m_query = 0;
|
||||
}
|
||||
|
||||
inline void swap(type& other)
|
||||
{
|
||||
m_cells.swap(other);
|
||||
|
||||
std::swap(m_count, other.m_count);
|
||||
key_hash::swap(other);
|
||||
}
|
||||
|
||||
inline size_t size() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
inline bool empty() const
|
||||
{
|
||||
return m_count == 0;
|
||||
}
|
||||
|
||||
struct iterator
|
||||
{
|
||||
iterator()
|
||||
: cell(~0u)
|
||||
, item(~0u)
|
||||
, grid(0)
|
||||
{
|
||||
}
|
||||
|
||||
value_type& operator*()
|
||||
{
|
||||
return grid->m_cells[cell][item];
|
||||
}
|
||||
|
||||
const value_type& operator*() const
|
||||
{
|
||||
return grid->m_cells[cell][item];
|
||||
}
|
||||
|
||||
value_type* operator->() const
|
||||
{
|
||||
return (&**this);
|
||||
}
|
||||
|
||||
iterator& operator++()
|
||||
{
|
||||
assert(cell < grid_type::CellCount);
|
||||
cell_type& items = grid->m_cells[cell];
|
||||
|
||||
if (!items.empty() && (item < items.size() - 1))
|
||||
{
|
||||
++item;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = 0;
|
||||
++cell;
|
||||
|
||||
while ((cell < type::CellCount) && grid->m_cells[cell].empty())
|
||||
{
|
||||
++cell;
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator++(int)
|
||||
{
|
||||
iterator tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
iterator& operator--()
|
||||
{
|
||||
if (item > 0)
|
||||
{
|
||||
--item;
|
||||
}
|
||||
else
|
||||
{
|
||||
--cell;
|
||||
while ((cell > 0) && grid->m_cells[cell].empty())
|
||||
{
|
||||
--cell;
|
||||
}
|
||||
|
||||
assert(cell < type::CellCount);
|
||||
cell_type& items = grid->m_cells[cell];
|
||||
item = items.size() - 1;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator--(int)
|
||||
{
|
||||
iterator tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(const iterator& other) const
|
||||
{
|
||||
return (cell == other.cell) && (item == other.item) && (grid == other.grid);
|
||||
}
|
||||
|
||||
bool operator!=(const iterator& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class hash_grid<NumberOfCells, ValueType, KeyHash, PositionRetriever>;
|
||||
typedef hash_grid<NumberOfCells, ValueType, KeyHash, PositionRetriever> grid_type;
|
||||
|
||||
iterator(size_t _cell, size_t _item, grid_type* _grid)
|
||||
: grid(_grid)
|
||||
, item(_item)
|
||||
, cell(_cell)
|
||||
{
|
||||
}
|
||||
|
||||
grid_type* grid;
|
||||
size_t cell;
|
||||
size_t item;
|
||||
};
|
||||
|
||||
inline iterator begin()
|
||||
{
|
||||
uint32 item = 0;
|
||||
uint32 cell = 0;
|
||||
|
||||
while ((cell < type::CellCount) && m_cells[cell].empty())
|
||||
{
|
||||
++cell;
|
||||
}
|
||||
|
||||
return iterator(cell, item, this);
|
||||
}
|
||||
|
||||
inline iterator end()
|
||||
{
|
||||
return iterator(CellCount, 0, this);
|
||||
}
|
||||
|
||||
inline iterator insert(const key_type& key, const value_type& value)
|
||||
{
|
||||
size_t hash_value = KeyHash::hash(key);
|
||||
size_t index = hash_value % CellCount;
|
||||
|
||||
cell_type& cell = m_cells[index];
|
||||
items_type& items = cell.items;
|
||||
|
||||
items.push_back(value);
|
||||
++m_count;
|
||||
|
||||
return iterator(index, items.size() - 1, this);
|
||||
}
|
||||
|
||||
inline void erase(const key_type& key, const value_type& value)
|
||||
{
|
||||
size_t hash_value = KeyHash::hash(key);
|
||||
size_t index = hash_value % CellCount;
|
||||
|
||||
cell_type& cell = m_cells[index];
|
||||
items_type& items = cell.items;
|
||||
|
||||
typename items_type::iterator it = items.begin();
|
||||
typename items_type::iterator end = items.end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
if (*it == value)
|
||||
{
|
||||
std::swap(*it, items.back());
|
||||
items.pop_back();
|
||||
--m_count;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline iterator erase(const iterator& it)
|
||||
{
|
||||
--m_count;
|
||||
cell_type& cell = m_cells[it.cell];
|
||||
items_type& items = cell.items;
|
||||
std::swap(items[it.item], items.back());
|
||||
items.pop_back();
|
||||
if (!items.empty())
|
||||
{
|
||||
return it;
|
||||
}
|
||||
|
||||
uint32 index = it.cell;
|
||||
while ((index < CellCount) && m_cells[index].items.empty())
|
||||
{
|
||||
++index;
|
||||
}
|
||||
|
||||
return iterator(index, 0, this);
|
||||
}
|
||||
|
||||
inline iterator find(const key_type& key, const value_type& value)
|
||||
{
|
||||
size_t index = KeyHash::hash(key) % CellCount;
|
||||
|
||||
cell_type& cell = m_cells[index];
|
||||
items_type& items = cell.items;
|
||||
typename items_type::iterator it = items.begin();
|
||||
typename items_type::iterator iend = items.end();
|
||||
|
||||
for (; it != iend; ++it)
|
||||
{
|
||||
if (*it == value)
|
||||
{
|
||||
return iterator(index, it - items.begin(), this);
|
||||
}
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
inline iterator move(const iterator& it, const key_type& to)
|
||||
{
|
||||
size_t index = KeyHash::hash(to) % CellCount;
|
||||
|
||||
if (index == it.cell)
|
||||
{
|
||||
return it;
|
||||
}
|
||||
|
||||
cell_type& cell = m_cells[it.cell];
|
||||
items_type& items = cell.items;
|
||||
typename items_type::iterator iit = items.begin() + it.item;
|
||||
|
||||
cell_type& to_cell = m_cells[index];
|
||||
items_type& to_items = to_cell.items;
|
||||
to_items.push_back(*iit);
|
||||
|
||||
std::swap(items[it.item], items.back());
|
||||
items.pop_back();
|
||||
|
||||
return iterator(index, to_items.size() - 1, this);
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
uint32 query_sphere(const key_type& center, const key_value& radius, Container& container) const
|
||||
{
|
||||
uint32 count = 0;
|
||||
|
||||
if (!empty())
|
||||
{
|
||||
++m_query;
|
||||
|
||||
key_type minc(center - key_type(radius));
|
||||
key_type maxc(center + key_type(radius));
|
||||
|
||||
discreet_type mind = KeyHash::discreet(minc);
|
||||
discreet_type maxd = KeyHash::discreet(maxc);
|
||||
discreet_type current = mind;
|
||||
|
||||
float radius_sq = radius * radius;
|
||||
|
||||
for (; current[0] <= maxd[0]; ++current[0])
|
||||
{
|
||||
for (; current[1] <= maxd[1]; ++current[1])
|
||||
{
|
||||
for (; current[2] <= maxd[2]; ++current[2])
|
||||
{
|
||||
size_t hash_value = KeyHash::hash(current);
|
||||
size_t index = hash_value % CellCount;
|
||||
|
||||
const cell_type& cell = m_cells[index];
|
||||
|
||||
if (cell.query != m_query)
|
||||
{
|
||||
cell.query = m_query;
|
||||
const items_type& items = cell.items;
|
||||
|
||||
typename items_type::const_iterator it = items.begin();
|
||||
typename items_type::const_iterator end = items.end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
if ((position(*it) - center).len2() <= radius_sq)
|
||||
{
|
||||
container.push_back(*it);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
current[2] = mind[2];
|
||||
}
|
||||
current[1] = mind[1];
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
uint32 query_sphere_distance(const key_type& center, const key_value& radius, Container& container) const
|
||||
{
|
||||
uint32 count = 0;
|
||||
|
||||
if (!empty())
|
||||
{
|
||||
++m_query;
|
||||
|
||||
key_type minc(center - key_type(radius));
|
||||
key_type maxc(center + key_type(radius));
|
||||
|
||||
discreet_type mind = KeyHash::discreet(minc);
|
||||
discreet_type maxd = KeyHash::discreet(maxc);
|
||||
discreet_type current = mind;
|
||||
|
||||
float radius_sq = radius * radius;
|
||||
|
||||
for (; current[0] <= maxd[0]; ++current[0])
|
||||
{
|
||||
for (; current[1] <= maxd[1]; ++current[1])
|
||||
{
|
||||
for (; current[2] <= maxd[2]; ++current[2])
|
||||
{
|
||||
size_t hash_value = KeyHash::hash(current);
|
||||
size_t index = hash_value % CellCount;
|
||||
|
||||
const cell_type& cell = m_cells[index];
|
||||
|
||||
if (cell.query != m_query)
|
||||
{
|
||||
cell.query = m_query;
|
||||
const items_type& items = cell.items;
|
||||
|
||||
typename items_type::const_iterator it = items.begin();
|
||||
typename items_type::const_iterator end = items.end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
float distance_sq = (position(*it) - center).len2();
|
||||
if (distance_sq <= radius_sq)
|
||||
{
|
||||
container.push_back(std::make_pair(distance_sq, *it));
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
current[2] = mind[2];
|
||||
}
|
||||
current[1] = mind[1];
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
uint32 query_box(const key_type& minc, const key_type& maxc, Container& container) const
|
||||
{
|
||||
uint32 count = 0;
|
||||
|
||||
if (!empty())
|
||||
{
|
||||
++m_query;
|
||||
|
||||
discreet_type mind = KeyHash::discreet(minc);
|
||||
discreet_type maxd = KeyHash::discreet(maxc);
|
||||
discreet_type current = mind;
|
||||
|
||||
for (; current[0] <= maxd[0]; ++current[0])
|
||||
{
|
||||
for (; current[1] <= maxd[1]; ++current[1])
|
||||
{
|
||||
for (; current[2] <= maxd[2]; ++current[2])
|
||||
{
|
||||
size_t hash_value = KeyHash::hash(current);
|
||||
size_t index = hash_value % CellCount;
|
||||
|
||||
const cell_type& cell = m_cells[index];
|
||||
|
||||
if (cell.query != m_query)
|
||||
{
|
||||
cell.query = m_query;
|
||||
const items_type& items = cell.items;
|
||||
|
||||
typename items_type::const_iterator it = items.begin();
|
||||
typename items_type::const_iterator end = items.end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
key_type pos = position(*it);
|
||||
|
||||
if (pos[0] >= minc[0] &&
|
||||
pos[1] >= minc[1] &&
|
||||
pos[2] >= minc[2] &&
|
||||
pos[0] <= maxc[0] &&
|
||||
pos[1] <= maxc[1] &&
|
||||
pos[2] <= maxc[2])
|
||||
{
|
||||
container.push_back(*it);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
current[2] = mind[2];
|
||||
}
|
||||
current[1] = mind[1];
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
protected:
|
||||
position_retriever_type position;
|
||||
cells_type m_cells;
|
||||
uint32 m_count;
|
||||
mutable uint32 m_query;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_HASHGRID_H
|
||||
@@ -1,250 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Containers that use their own heap for allocation.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_HEAPCONTAINER_H
|
||||
#define CRYINCLUDE_CRYCOMMON_HEAPCONTAINER_H
|
||||
#pragma once
|
||||
|
||||
#include "PoolAllocator.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T, typename L = stl::PSyncMultiThread>
|
||||
struct HeapQueue
|
||||
: public L
|
||||
{
|
||||
typedef typename L::Lock Lock;
|
||||
|
||||
HeapQueue()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
T* push_back()
|
||||
{
|
||||
Lock lock(*this);
|
||||
return push_back(m_Allocator.New());
|
||||
}
|
||||
|
||||
template<class I>
|
||||
T* push_back(I const& init)
|
||||
{
|
||||
Lock lock(*this);
|
||||
Node* pNode = (Node*)m_Allocator.Allocate();
|
||||
new(static_cast<T*>(pNode))T(init);
|
||||
return push_back(pNode);
|
||||
}
|
||||
|
||||
template<class I, class J>
|
||||
T* push_back(I const& i, J const& j)
|
||||
{
|
||||
Lock lock(*this);
|
||||
Node* pNode = (Node*)m_Allocator.Allocate();
|
||||
new(static_cast<T*>(pNode))T(i, j);
|
||||
return push_back(pNode);
|
||||
}
|
||||
|
||||
T* pop_front()
|
||||
{
|
||||
Lock lock(*this);
|
||||
|
||||
// Quick check, before locking.
|
||||
if (empty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Node* pNode = *m_ppHead;
|
||||
if (pNode)
|
||||
{
|
||||
m_ppHead = &(*m_ppHead)->pNext;
|
||||
m_nQueued--;
|
||||
validate();
|
||||
}
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
Lock lock(*this);
|
||||
|
||||
validate();
|
||||
|
||||
// Destruct all elements.
|
||||
size_t nCheckAlloc = 0;
|
||||
while (m_pList)
|
||||
{
|
||||
nCheckAlloc++;
|
||||
Node* pNext = m_pList->pNext;
|
||||
m_pList->~Node();
|
||||
m_pList = pNext;
|
||||
}
|
||||
assert(nCheckAlloc == m_nAlloc);
|
||||
|
||||
// Empty queue structure.
|
||||
reset();
|
||||
|
||||
// Free pool memory all at once.
|
||||
m_Allocator.FreeMemory(false);
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return m_nQueued;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return m_nQueued == 0;
|
||||
}
|
||||
|
||||
size_t allocated_memory() const
|
||||
{
|
||||
// Amortise allocated mem over all list instances.
|
||||
Lock lock(*this);
|
||||
return m_Allocator.GetTotalMemory().nAlloc;
|
||||
}
|
||||
|
||||
// Additional lock against storage deletion.
|
||||
L ClearLock;
|
||||
|
||||
void GetMemoryUsage(ICrySizer* pSizer) const
|
||||
{
|
||||
pSizer->AddObject(m_Allocator);
|
||||
}
|
||||
protected:
|
||||
|
||||
struct Node
|
||||
: T
|
||||
{
|
||||
Node* pNext;
|
||||
};
|
||||
|
||||
Node* m_pList; // First (allocated) node in list.
|
||||
Node** m_ppHead; // Points to pointer to front of queue, for popping.
|
||||
Node** m_ppTail; // Points to pointer at end of list, and of queue, for pushing.
|
||||
size_t m_nAlloc, m_nQueued;
|
||||
|
||||
void validate()
|
||||
{
|
||||
assert(m_nQueued <= m_nAlloc);
|
||||
assert(m_ppHead);
|
||||
assert(m_ppTail);
|
||||
assert(!*m_ppTail);
|
||||
assert((m_nQueued == 0) == !*m_ppHead);
|
||||
assert((m_nQueued == 0) == (m_ppHead == m_ppTail));
|
||||
assert((m_nAlloc == 0) == (m_ppTail == &m_pList));
|
||||
assert((m_nAlloc == 0) == !m_pList);
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_pList = 0;
|
||||
m_ppHead = m_ppTail = &m_pList;
|
||||
m_nAlloc = m_nQueued = 0;
|
||||
validate();
|
||||
}
|
||||
|
||||
Node* push_back(Node* pNode)
|
||||
{
|
||||
pNode->pNext = 0;
|
||||
|
||||
*m_ppTail = pNode;
|
||||
m_ppTail = &pNode->pNext;
|
||||
m_nAlloc++;
|
||||
m_nQueued++;
|
||||
|
||||
validate();
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
// Allocate all elements from an exclusive pool.
|
||||
// Any locking is performed by the queue, no further locking needed in allocator.
|
||||
stl::TPoolAllocator<Node, stl::PSyncNone> m_Allocator;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T, class C = std::less<T>, typename L = stl::PSyncNone>
|
||||
struct HeapPriorityQueue
|
||||
: public HeapQueue<T, L>
|
||||
{
|
||||
// Hand-holding for brain-dead template compiler.
|
||||
typedef HeapQueue<T, L> super;
|
||||
typedef typename super::Node Node;
|
||||
using super::empty;
|
||||
using super::validate;
|
||||
using super::m_ppHead;
|
||||
using super::m_ppTail;
|
||||
using super::m_nQueued;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename super::Lock Lock;
|
||||
|
||||
// Pop the "largest" element, using class C.
|
||||
T* pop_largest()
|
||||
{
|
||||
Lock lock(*this);
|
||||
|
||||
if (!empty())
|
||||
{
|
||||
C comp;
|
||||
|
||||
// Find highest-valued item.
|
||||
// To do: improve linear search! Use priority queue.
|
||||
Node** ppTop = m_ppHead;
|
||||
for (Node** ppNode = &(*m_ppHead)->pNext; *ppNode; ppNode = &(*ppNode)->pNext)
|
||||
{
|
||||
if (comp(**ppTop, **ppNode))
|
||||
{
|
||||
ppTop = ppNode;
|
||||
}
|
||||
}
|
||||
Node* pTop = *ppTop;
|
||||
|
||||
// Move link to head.
|
||||
if (ppTop != m_ppHead)
|
||||
{
|
||||
if (!pTop->pNext)
|
||||
{
|
||||
// End of list.
|
||||
m_ppTail = ppTop;
|
||||
}
|
||||
*ppTop = pTop->pNext;
|
||||
pTop->pNext = *m_ppHead;
|
||||
*m_ppHead = pTop;
|
||||
}
|
||||
|
||||
// Pop head.
|
||||
m_ppHead = &pTop->pNext;
|
||||
m_nQueued--;
|
||||
|
||||
validate();
|
||||
return pTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void GetMemoryUsage(ICrySizer* pSizer) const
|
||||
{
|
||||
HeapQueue<T, L>::GetMemoryUsage(pSizer);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_HEAPCONTAINER_H
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_ICHUNKFILE_H
|
||||
#define CRYINCLUDE_CRYCOMMON_ICHUNKFILE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "CryHeaders.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Description:
|
||||
// Chunked File (.cgf, .chr etc.) interface
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct IChunkFile
|
||||
: _reference_target_t
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Chunk Description.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct ChunkDesc
|
||||
{
|
||||
ChunkTypes chunkType;
|
||||
int chunkVersion;
|
||||
int chunkId;
|
||||
uint32 fileOffset;
|
||||
void* data;
|
||||
uint32 size;
|
||||
bool bSwapEndian;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
ChunkDesc()
|
||||
: chunkType(ChunkType_ANY)
|
||||
, chunkVersion(0)
|
||||
, chunkId(0)
|
||||
, fileOffset(0)
|
||||
, data(0)
|
||||
, size(0)
|
||||
, bSwapEndian(false)
|
||||
{
|
||||
}
|
||||
|
||||
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{ /*nothing*/}
|
||||
|
||||
static inline bool LessOffset(const ChunkDesc& d1, const ChunkDesc& d2) { return d1.fileOffset < d2.fileOffset; }
|
||||
static inline bool LessOffsetByPtr(const ChunkDesc* d1, const ChunkDesc* d2) { return d1->fileOffset < d2->fileOffset; }
|
||||
static inline bool LessId(const ChunkDesc& d1, const ChunkDesc& d2) { return d1.chunkId < d2.chunkId; }
|
||||
};
|
||||
|
||||
// <interfuscator:shuffle>
|
||||
|
||||
virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0;
|
||||
|
||||
// Releases chunk file interface.
|
||||
virtual void Release() = 0;
|
||||
|
||||
virtual bool IsReadOnly() const = 0;
|
||||
virtual bool IsLoaded() const = 0;
|
||||
|
||||
virtual bool Read(const char* filename) = 0;
|
||||
virtual bool ReadFromMemory(const void* pData, int nDataSize) = 0;
|
||||
|
||||
// Writes chunks to file.
|
||||
virtual bool Write(const char* filename) = 0;
|
||||
// Writes chunks to a memory buffer (allocated inside) and returns
|
||||
// pointer to the allocated memory (pData) and its size (nSize).
|
||||
// The memory will be released on destruction of the ChunkFile object, or
|
||||
// on the next WriteToMemoryBuffer() call, or on ReleaseMemoryBuffer() call.
|
||||
virtual bool WriteToMemoryBuffer(void** pData, int* nSize) = 0;
|
||||
// Releases memory that was allocated in WriteToMemoryBuffer()
|
||||
virtual void ReleaseMemoryBuffer() = 0;
|
||||
|
||||
// Adds chunk to file, returns ChunkID of the added chunk.
|
||||
virtual int AddChunk(ChunkTypes chunkType, int chunkVersion, EEndianness eEndianness, const void* chunkData, int chunkSize) = 0;
|
||||
virtual void DeleteChunkById(int nChunkId) = 0;
|
||||
virtual void DeleteChunksByType(ChunkTypes nChunkType) = 0;
|
||||
|
||||
virtual ChunkDesc* FindChunkByType(ChunkTypes nChunkType) = 0;
|
||||
virtual ChunkDesc* FindChunkById(int nChunkId) = 0;
|
||||
|
||||
// Gets the number of chunks.
|
||||
virtual int NumChunks() const = 0;
|
||||
|
||||
// Gets chunk description at i-th index.
|
||||
virtual ChunkDesc* GetChunk(int nIndex) = 0;
|
||||
virtual const ChunkDesc* GetChunk(int nIndex) const = 0;
|
||||
|
||||
virtual const char* GetLastError() const = 0;
|
||||
|
||||
// </interfuscator:shuffle>
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_ICHUNKFILE_H
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_ICOLORGRADINGCONTROLLER_H
|
||||
#define CRYINCLUDE_CRYCOMMON_ICOLORGRADINGCONTROLLER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
struct SColorChartLayer
|
||||
{
|
||||
int m_texID;
|
||||
float m_blendAmount;
|
||||
|
||||
SColorChartLayer()
|
||||
: m_texID(-1)
|
||||
, m_blendAmount(-1)
|
||||
{
|
||||
}
|
||||
|
||||
SColorChartLayer(int texID, float blendAmount)
|
||||
: m_texID(texID)
|
||||
, m_blendAmount(blendAmount)
|
||||
{
|
||||
}
|
||||
|
||||
SColorChartLayer(const SColorChartLayer& rhs)
|
||||
: m_texID(rhs.m_texID)
|
||||
, m_blendAmount(rhs.m_blendAmount)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct IColorGradingController
|
||||
{
|
||||
public:
|
||||
// <interfuscator:shuffle>
|
||||
virtual ~IColorGradingController(){}
|
||||
virtual int LoadColorChart(const char* pChartFilePath) const = 0;
|
||||
virtual int LoadDefaultColorChart() const = 0;
|
||||
virtual void UnloadColorChart(int texID) const = 0;
|
||||
|
||||
virtual void SetLayers(const SColorChartLayer* pLayers, uint32 numLayers) = 0;
|
||||
// </interfuscator:shuffle>
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_ICOLORGRADINGCONTROLLER_H
|
||||
@@ -27,7 +27,6 @@ namespace AZ
|
||||
struct IMaterial;
|
||||
struct IVisArea;
|
||||
struct SRenderingPassInfo;
|
||||
struct IGeomCache;
|
||||
struct SRendItemSorter;
|
||||
struct SFrameLodInfo;
|
||||
struct pe_params_area;
|
||||
@@ -259,9 +258,6 @@ struct IRenderNode
|
||||
virtual struct IStatObj* GetEntityStatObj(unsigned int nPartId = 0, unsigned int nSubPartId = 0, Matrix34A* pMatrix = NULL, bool bReturnOnlyVisible = false);
|
||||
virtual _smart_ptr<IMaterial> GetEntitySlotMaterial([[maybe_unused]] unsigned int nPartId, [[maybe_unused]] bool bReturnOnlyVisible = false, [[maybe_unused]] bool* pbDrawNear = NULL) { return NULL; }
|
||||
virtual void SetEntityStatObj([[maybe_unused]] unsigned int nSlot, [[maybe_unused]] IStatObj* pStatObj, [[maybe_unused]] const Matrix34A* pMatrix = NULL) {};
|
||||
#if defined(USE_GEOM_CACHES)
|
||||
virtual struct IGeomCacheRenderNode* GetGeomCacheRenderNode([[maybe_unused]] unsigned int nSlot, [[maybe_unused]] Matrix34A* pMatrix = NULL, [[maybe_unused]] bool bReturnOnlyVisible = false) { return NULL; }
|
||||
#endif
|
||||
virtual int GetSlotCount() const { return 1; }
|
||||
|
||||
// Summary:
|
||||
@@ -793,81 +789,4 @@ struct IPrismRenderNode
|
||||
};
|
||||
#endif // EXCLUDE_DOCUMENTATION_PURPOSE
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(USE_GEOM_CACHES)
|
||||
struct IGeomCacheRenderNode
|
||||
: public IRenderNode
|
||||
{
|
||||
virtual bool LoadGeomCache(const char* sGeomCacheFileName) = 0;
|
||||
|
||||
virtual void SetGeomCache(_smart_ptr<IGeomCache> geomCache) = 0;
|
||||
|
||||
// Gets the geometry cache that is rendered
|
||||
virtual IGeomCache* GetGeomCache() const = 0;
|
||||
|
||||
// Sets the time in the animation for the current frame.
|
||||
// Note that you should start streaming before calling this.
|
||||
virtual void SetPlaybackTime(const float time) = 0;
|
||||
|
||||
// Get the current playback time
|
||||
virtual float GetPlaybackTime() const = 0;
|
||||
|
||||
// Check if cache is streaming.
|
||||
virtual bool IsStreaming() const = 0;
|
||||
|
||||
// Need to start streaming before playback, otherwise there will be stalls.
|
||||
virtual void StartStreaming(const float time = 0.0f) = 0;
|
||||
|
||||
// Stops streaming and trashes the buffers
|
||||
virtual void StopStreaming() = 0;
|
||||
|
||||
// Checks if looping is enabled
|
||||
virtual bool IsLooping() const = 0;
|
||||
|
||||
// Enable/disable looping playback
|
||||
virtual void SetLooping(const bool bEnable) = 0;
|
||||
|
||||
// Gets time delta from current playback position to last ready to play frame
|
||||
virtual float GetPrecachedTime() const = 0;
|
||||
|
||||
// Check if bounds changed since last call to this function
|
||||
virtual bool DidBoundsChange() = 0;
|
||||
|
||||
// Set stand in CGFs and distance
|
||||
virtual void SetStandIn(const char* pFilePath, const char* pMaterial) = 0;
|
||||
virtual IStatObj* GetStandIn() = 0;
|
||||
virtual void SetFirstFrameStandIn(const char* pFilePath, const char* pMaterial) = 0;
|
||||
virtual IStatObj* GetFirstFrameStandIn() = 0;
|
||||
virtual void SetLastFrameStandIn(const char* pFilePath, const char* pMaterial) = 0;
|
||||
virtual IStatObj* GetLastFrameStandIn() = 0;
|
||||
virtual void SetStandInDistance(const float distance) = 0;
|
||||
virtual float GetStandInDistance() = 0;
|
||||
|
||||
// Set distance at which cache will start streaming automatically (0 means no auto streaming)
|
||||
virtual void SetStreamInDistance(const float distance) = 0;
|
||||
virtual float GetStreamInDistance() = 0;
|
||||
|
||||
// Start/Stop drawing the cache
|
||||
virtual void SetDrawing(bool bDrawing) = 0;
|
||||
|
||||
// Debug draw geometry
|
||||
virtual void DebugDraw(const struct SGeometryDebugDrawInfo& info, float fExtrudeScale = 0.01f, uint nodeIndex = 0) const = 0;
|
||||
|
||||
// Ray intersection against cache
|
||||
virtual bool RayIntersection(struct SRayHitInfo& hitInfo, _smart_ptr<IMaterial> pCustomMtl = NULL, uint* pHitNodeIndex = NULL) const = 0;
|
||||
|
||||
// Set max view distance
|
||||
virtual void SetBaseMaxViewDistance(float maxViewDistance) = 0;
|
||||
|
||||
// Get node information
|
||||
virtual uint GetNodeCount() const = 0;
|
||||
virtual Matrix34 GetNodeTransform(const uint nodeIndex) const = 0;
|
||||
virtual const char* GetNodeName(const uint nodeIndex) const = 0; // Node name is only stored in editor
|
||||
virtual uint32 GetNodeNameHash(const uint nodeIndex) const = 0;
|
||||
virtual bool IsNodeDataValid(const uint nodeIndex) const = 0; // Returns false if cache isn't loaded yet or index is out of range
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IENTITYRENDERSTATE_H
|
||||
|
||||
@@ -1,268 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_IFUNCVARIABLE_H
|
||||
#define CRYINCLUDE_CRYCOMMON_IFUNCVARIABLE_H
|
||||
#pragma once
|
||||
|
||||
#include "Cry_Vector2.h"
|
||||
#include "Cry_Vector3.h"
|
||||
#include "Cry_Matrix33.h"
|
||||
#include "Cry_Color.h"
|
||||
#include "smartptr.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
class ITexture;
|
||||
|
||||
enum FuncParamType
|
||||
{
|
||||
e_FLOAT, e_INT, e_BOOL, e_VEC2, e_VEC3, e_VEC4, e_COLOR, e_MATRIX33,
|
||||
// Though all types of textures are using the same class, it's important for editor to differentiate between them:
|
||||
e_TEXTURE2D, e_TEXTURE3D, e_TEXTURE_CUBE
|
||||
};
|
||||
|
||||
class IFuncVariable
|
||||
: public _reference_target_t
|
||||
{
|
||||
public:
|
||||
// <interfuscator:shuffle>
|
||||
virtual ~IFuncVariable(){};
|
||||
|
||||
virtual float GetMin() const = 0;
|
||||
virtual float GetMax() const = 0;
|
||||
|
||||
virtual void InvokeSetter(void* param) = 0;
|
||||
|
||||
virtual int GetInt() const = 0;
|
||||
virtual float GetFloat() const = 0;
|
||||
virtual bool GetBool() const = 0;
|
||||
virtual Vec2 GetVec2() const = 0;
|
||||
virtual Vec3 GetVec3() const = 0;
|
||||
virtual Vec4 GetVec4() const = 0;
|
||||
virtual ColorF GetColorF() const = 0;
|
||||
virtual Matrix33 GetMatrix33() const = 0;
|
||||
virtual ITexture* GetTexture() const = 0;
|
||||
// </interfuscator:shuffle>
|
||||
|
||||
enum FuncParamType paramType; // float, string, int, vec3 etc
|
||||
string name;
|
||||
#if defined(FLARES_SUPPORT_EDITING)
|
||||
string humanName;
|
||||
string description;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class MFPVariable
|
||||
: public IFuncVariable
|
||||
{
|
||||
public:
|
||||
typedef void (T::* OpticsBase_MFPtr)();
|
||||
OpticsBase_MFPtr pSetter;
|
||||
OpticsBase_MFPtr pGetter;
|
||||
T* pObj;
|
||||
std::pair<float, float> range;
|
||||
|
||||
private:
|
||||
MFPVariable ()
|
||||
{
|
||||
Set(e_INT, "", "", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
float GetMin() const override { return range.first; }
|
||||
float GetMax() const override { return range.second; }
|
||||
|
||||
MFPVariable(FuncParamType type, const char* _humanname, const char* _description, T* obj, OpticsBase_MFPtr setter, OpticsBase_MFPtr getter, float fMin = 0, float fMax = 1.0f)
|
||||
{
|
||||
Set(type, _humanname, _description, obj, setter, getter, fMin, fMax);
|
||||
}
|
||||
|
||||
void Set(FuncParamType type, const char* _humanname, const char* _description, T* obj, OpticsBase_MFPtr setter, OpticsBase_MFPtr getter, float fMin = 0, float fMax = 1.0f)
|
||||
{
|
||||
paramType = type;
|
||||
|
||||
char _nameNoSpace[50];
|
||||
cry_strcpy(_nameNoSpace, _humanname);
|
||||
char* p1 = _nameNoSpace;
|
||||
char* p2 = p1;
|
||||
while (*p1 != 0)
|
||||
{
|
||||
if ((*p1) == ' ')
|
||||
{
|
||||
++p1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p2++ = *p1++;
|
||||
}
|
||||
}
|
||||
|
||||
*p2 = 0;
|
||||
name = _nameNoSpace;
|
||||
|
||||
#if defined(FLARES_SUPPORT_EDITING)
|
||||
humanName = _humanname;
|
||||
description = _description;
|
||||
#endif
|
||||
|
||||
pObj = obj;
|
||||
pSetter = setter;
|
||||
pGetter = getter;
|
||||
range.first = fMin;
|
||||
range.second = fMax;
|
||||
}
|
||||
|
||||
#define INVOKE_SETTER(PARAM_TYPE, param) (pObj->*(reinterpret_cast<void (T::*)(PARAM_TYPE)>(pSetter)))(*(PARAM_TYPE*)param)
|
||||
#define INVOKE_SETTER_P(PARAM_TYPE, param) (pObj->*(reinterpret_cast<void (T::*)(PARAM_TYPE)>(pSetter)))((PARAM_TYPE)param)
|
||||
|
||||
void InvokeSetter(void* param) override
|
||||
{
|
||||
switch (paramType)
|
||||
{
|
||||
case e_FLOAT:
|
||||
INVOKE_SETTER(float, param);
|
||||
break;
|
||||
case e_INT:
|
||||
INVOKE_SETTER(int, param);
|
||||
break;
|
||||
case e_VEC2:
|
||||
INVOKE_SETTER(Vec2, param);
|
||||
break;
|
||||
case e_VEC3:
|
||||
INVOKE_SETTER(Vec3, param);
|
||||
break;
|
||||
case e_VEC4:
|
||||
INVOKE_SETTER(Vec4, param);
|
||||
break;
|
||||
case e_BOOL:
|
||||
INVOKE_SETTER(bool, param);
|
||||
break;
|
||||
case e_COLOR:
|
||||
INVOKE_SETTER(ColorF, param);
|
||||
break;
|
||||
case e_MATRIX33:
|
||||
INVOKE_SETTER(Matrix33, param);
|
||||
break;
|
||||
case e_TEXTURE2D:
|
||||
INVOKE_SETTER_P(ITexture*, param);
|
||||
break;
|
||||
case e_TEXTURE3D:
|
||||
INVOKE_SETTER_P(ITexture*, param);
|
||||
break;
|
||||
case e_TEXTURE_CUBE:
|
||||
INVOKE_SETTER_P(ITexture*, param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define INVOKE_GETTER(PARAM_TYPE) ((pObj->*reinterpret_cast<PARAM_TYPE (T::*)()>(pGetter))())
|
||||
|
||||
int GetInt() const override {return INVOKE_GETTER(int); }
|
||||
float GetFloat() const override {return INVOKE_GETTER(float); }
|
||||
bool GetBool() const override {return INVOKE_GETTER(bool); }
|
||||
Vec2 GetVec2() const override {return INVOKE_GETTER(Vec2); }
|
||||
Vec3 GetVec3() const override {return INVOKE_GETTER(Vec3); }
|
||||
Vec4 GetVec4() const override {return INVOKE_GETTER(Vec4); }
|
||||
ColorF GetColorF() const override {return INVOKE_GETTER(ColorF); }
|
||||
Matrix33 GetMatrix33() const override {return INVOKE_GETTER(Matrix33); }
|
||||
ITexture* GetTexture() const override {return INVOKE_GETTER(ITexture*); }
|
||||
};
|
||||
|
||||
class FuncVariableGroup
|
||||
{
|
||||
private:
|
||||
AZStd::vector<_smart_ptr<IFuncVariable> > variables;
|
||||
string m_name;
|
||||
#if defined(FLARES_SUPPORT_EDITING)
|
||||
string m_humanname;
|
||||
#endif
|
||||
bool bCollapse;
|
||||
|
||||
public:
|
||||
FuncVariableGroup()
|
||||
: bCollapse(false)
|
||||
{
|
||||
SetName("");
|
||||
}
|
||||
|
||||
~FuncVariableGroup()
|
||||
{
|
||||
}
|
||||
|
||||
void SetName(const char* name, [[maybe_unused]] const char* humanname = 0)
|
||||
{
|
||||
if (!name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_name = name;
|
||||
#if defined(FLARES_SUPPORT_EDITING)
|
||||
m_humanname = humanname ? humanname : name;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* GetName()
|
||||
{
|
||||
return m_name.c_str();
|
||||
}
|
||||
|
||||
#if defined(FLARES_SUPPORT_EDITING)
|
||||
const char* GetHumanName()
|
||||
{
|
||||
return m_humanname.c_str();
|
||||
}
|
||||
#endif
|
||||
|
||||
void SetCollapse(bool _bCollapse)
|
||||
{
|
||||
bCollapse = _bCollapse;
|
||||
}
|
||||
|
||||
bool IsCollapse()
|
||||
{
|
||||
return bCollapse;
|
||||
}
|
||||
|
||||
IFuncVariable* FindVariable(const char* name)
|
||||
{
|
||||
for (int i = 0, iSize(variables.size()); i < iSize; ++i)
|
||||
{
|
||||
if (variables[i] == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(variables[i]->name.c_str(), name))
|
||||
{
|
||||
return variables[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SetVariable(int nIndex, IFuncVariable* v){ variables[nIndex] = v; }
|
||||
|
||||
int GetVariableCount() { return variables.size(); }
|
||||
|
||||
IFuncVariable* GetVariable(int nIndex)
|
||||
{
|
||||
return variables[nIndex];
|
||||
}
|
||||
|
||||
void AddVariable(IFuncVariable* var)
|
||||
{
|
||||
variables.push_back(var);
|
||||
}
|
||||
};
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IFUNCVARIABLE_H
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Interface for CGeomCache class
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_IGEOMCACHE_H
|
||||
#define CRYINCLUDE_CRYCOMMON_IGEOMCACHE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "smartptr.h" // TYPEDEF_AUTOPTR
|
||||
|
||||
// Summary:
|
||||
// Interface to hold geom cache data
|
||||
struct IGeomCache
|
||||
: public IStreamable
|
||||
{
|
||||
// Description:
|
||||
// Increase the reference count of the object.
|
||||
// Summary:
|
||||
// Notifies that the object is being used
|
||||
virtual int AddRef() = 0;
|
||||
|
||||
// Description:
|
||||
// Decrease the reference count of the object. If the reference count
|
||||
// reaches zero, the object will be deleted from memory.
|
||||
// Summary:
|
||||
// Notifies that the object is no longer needed
|
||||
virtual int Release() = 0;
|
||||
|
||||
// Description:
|
||||
// Checks if the geometry cache was successfully loaded from disk
|
||||
// Return Value:
|
||||
// True if valid, otherwise false
|
||||
virtual bool IsValid() const = 0;
|
||||
|
||||
// Description:
|
||||
// Set default material for the geometry.
|
||||
// Arguments:
|
||||
// pMaterial - A valid pointer to the material.
|
||||
virtual void SetMaterial(_smart_ptr<IMaterial> pMaterial) = 0;
|
||||
|
||||
// Description:
|
||||
// Returns default material of the geometry.
|
||||
// Arguments:
|
||||
// nType - Pass 0 to get the physic geometry or pass 1 to get the obstruct geometry
|
||||
// Return Value:
|
||||
// A pointer to a phys_geometry class.
|
||||
virtual _smart_ptr<IMaterial> GetMaterial() = 0;
|
||||
virtual const _smart_ptr<IMaterial> GetMaterial() const = 0;
|
||||
|
||||
// Summary:
|
||||
// Returns the filename of the object
|
||||
// Return Value:
|
||||
// A null terminated string which contain the filename of the object.
|
||||
virtual const char* GetFilePath() const = 0;
|
||||
|
||||
// Summary:
|
||||
// Returns the duration of the geom cache animation
|
||||
// Return value:
|
||||
// float value in seconds
|
||||
virtual float GetDuration() const = 0;
|
||||
|
||||
// Summary:
|
||||
// Reloads the cache. Need to call this when cache file changed.
|
||||
virtual void Reload() = 0;
|
||||
|
||||
// Summary:
|
||||
// Returns the max AABB of the geom cache through the whole animation
|
||||
// Return value:
|
||||
// The geom cache's max axis aligned bounding box
|
||||
virtual const AABB& GetAABB() const = 0;
|
||||
|
||||
/**
|
||||
* Tells the GeomCache whether or not it can release its static mesh data
|
||||
*
|
||||
* For the new AZ Geom Cache asset we have to be able
|
||||
* to tell the Geom Cache not to release loaded data.
|
||||
* This only matters when Geom Caches are not streamed.
|
||||
*
|
||||
* The legacy system works like this (if e_streamCGF is 0):
|
||||
* Load a geom cache entity.
|
||||
* Entity creates a geom cache render node.
|
||||
* Node loads geom cache, cache is marked as loaded.
|
||||
* Render node immediately initializes with the Geom Cache data.
|
||||
* Because the Geom Cache is not streamed, it releases unneeded data next tick
|
||||
*
|
||||
* The AZ system works like this:
|
||||
* Geom Cache component is created
|
||||
* Asset is requested
|
||||
* Asset loads Geom Cache
|
||||
* Geom Cache loads data and is marked as loaded
|
||||
* Asset calls AllowReleaseLoadedData(false) and locks loaded state
|
||||
* Tick happens and data is not freed (this is good, we need that data)
|
||||
* OnAssetReady event fires and is picked up by Geom Cache Component
|
||||
* Data is fed from the asset to the Geom Cache Render Node
|
||||
* Component calls AllowReleaseLoadedData(true)
|
||||
* Next tick the Geom Cache cleans up unneeded data
|
||||
*/
|
||||
virtual void SetProcessedByRenderNode(bool) = 0;
|
||||
|
||||
// Summary:
|
||||
// Returns statistics
|
||||
// Return value:
|
||||
// SStatistics struct
|
||||
struct SStatistics
|
||||
{
|
||||
bool m_bPlaybackFromMemory;
|
||||
float m_averageAnimationDataRate;
|
||||
uint m_numStaticMeshes;
|
||||
uint m_numStaticVertices;
|
||||
uint m_numStaticTriangles;
|
||||
uint m_numAnimatedMeshes;
|
||||
uint m_numAnimatedVertices;
|
||||
uint m_numAnimatedTriangles;
|
||||
uint m_numMaterials;
|
||||
uint m_staticDataSize;
|
||||
uint m_diskAnimationDataSize;
|
||||
uint m_memoryAnimationDataSize;
|
||||
};
|
||||
|
||||
virtual SStatistics GetStatistics() const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~IGeomCache() {}; // should be never called, use Release() instead
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IGEOMCACHE_H
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_IIMAGE_H
|
||||
#define CRYINCLUDE_CRYCOMMON_IIMAGE_H
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Possible errors for IImageFile::mfGet_error.
|
||||
*/
|
||||
enum EImFileError
|
||||
{
|
||||
eIFE_OK = 0, eIFE_IOerror, eIFE_OutOfMemory, eIFE_BadFormat, eIFE_ChunkNotFound
|
||||
};
|
||||
|
||||
// here are all of the flags that can be passed into the image load flags
|
||||
#define FIM_NORMALMAP 0x0001
|
||||
#define FIM_NOTSUPPORTS_MIPS 0x0004
|
||||
#define FIM_ALPHA 0x0008 // request attached alpha image
|
||||
#define FIM_DECAL 0x0010
|
||||
#define FIM_GREYSCALE 0x0020 // hint this texture is greyscale (could be DXT1 with colored artifacts)
|
||||
#define FIM_STREAM_PREPARE 0x0080
|
||||
#define FIM_UNUSED_BIT 0x0100 // Free to use
|
||||
#define FIM_BIG_ENDIANNESS 0x0400 // for textures converted to big endianness format
|
||||
#define FIM_SPLITTED 0x0800 // for dds textures stored in splitted files
|
||||
#define FIM_SRGB_READ 0x1000
|
||||
#define FIM_X360_NOT_PRETILED 0x2000 // for dds textures that cannot be pretiled
|
||||
#define FIM_UNUSED_BIT_1 0x4000 // Free to use
|
||||
#define FIM_RENORMALIZED_TEXTURE 0x8000 // for dds textures with EIF_RenormalizedTexture set in the dds header (not currently supported in the engine at runtime)
|
||||
#define FIM_HAS_ATTACHED_ALPHA 0x10000 // image has an attached alpha image
|
||||
#define FIM_SUPPRESS_DOWNSCALING 0x20000 // don't allow to drop mips when texture is non-streamable
|
||||
#define FIM_DX10IO 0x40000 // for dds textures with extended DX10+ header
|
||||
#define FIM_NOFALLBACKS 0x80000 // if the texture can't be loaded or is not found, do not replace it with a default 'not found' texture.
|
||||
|
||||
class IImageFile
|
||||
{
|
||||
public:
|
||||
virtual int AddRef() = 0;
|
||||
virtual int Release() = 0;
|
||||
|
||||
virtual const string& mfGet_filename () const = 0;
|
||||
|
||||
virtual int mfGet_width () const = 0;
|
||||
virtual int mfGet_height () const = 0;
|
||||
virtual int mfGet_depth () const = 0;
|
||||
virtual int mfGet_NumSides () const = 0;
|
||||
|
||||
virtual EImFileError mfGet_error () const = 0;
|
||||
|
||||
virtual byte* mfGet_image (const int nSide) = 0;
|
||||
virtual bool mfIs_image (const int nSide) const = 0;
|
||||
|
||||
virtual ETEX_Format mfGetFormat() const = 0;
|
||||
virtual ETEX_TileMode mfGetTileMode() const = 0;
|
||||
virtual int mfGet_numMips () const = 0;
|
||||
virtual int mfGet_numPersistentMips () const = 0;
|
||||
virtual int mfGet_Flags () const = 0;
|
||||
virtual const ColorF& mfGet_minColor () const = 0;
|
||||
virtual const ColorF& mfGet_maxColor () const = 0;
|
||||
virtual int mfGet_ImageSize() const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~IImageFile() {}
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IIMAGE_H
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_IMESHBAKING_H
|
||||
#define CRYINCLUDE_CRYCOMMON_IMESHBAKING_H
|
||||
#pragma once
|
||||
|
||||
|
||||
struct SMeshBakingMaterialParams
|
||||
{
|
||||
float rayLength;
|
||||
float rayIndent;
|
||||
bool bAlphaCutout;
|
||||
bool bIgnore;
|
||||
};
|
||||
|
||||
struct SMeshBakingInputParams
|
||||
{
|
||||
IStatObj* pCageMesh;
|
||||
IStatObj* pInputMesh;
|
||||
const SMeshBakingMaterialParams* pMaterialParams;
|
||||
ColorF defaultBackgroundColour;
|
||||
ColorF dilateMagicColour;
|
||||
int outputTextureWidth;
|
||||
int outputTextureHeight;
|
||||
int numMaterialParams;
|
||||
int nLodId;
|
||||
bool bDoDilationPass;
|
||||
bool bSmoothNormals;
|
||||
bool bSaveSpecular;
|
||||
_smart_ptr<IMaterial> pMaterial;
|
||||
};
|
||||
|
||||
struct SMeshBakingOutput
|
||||
{
|
||||
ITexture* ppOuputTexture[3];
|
||||
ITexture* ppIntermediateTexture[3];
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IMESHBAKING_H
|
||||
@@ -1,252 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
struct IStreamable;
|
||||
struct SCheckOcclusionJobData;
|
||||
struct SCheckOcclusionOutput;
|
||||
class COctreeNode;
|
||||
struct IStatInstGroup;
|
||||
|
||||
namespace NAsyncCull
|
||||
{
|
||||
class CCullThread;
|
||||
}
|
||||
|
||||
// Inplace object for IStreamable* to cache StreamableMemoryContentSize
|
||||
struct SStreamAbleObject
|
||||
{
|
||||
explicit SStreamAbleObject(IStreamable* pObj, bool bUpdateMemUsage = true)
|
||||
: m_pObj(pObj)
|
||||
, fCurImportance(-1000.f)
|
||||
{
|
||||
if (pObj && bUpdateMemUsage)
|
||||
{
|
||||
m_nStreamableContentMemoryUsage = pObj->GetStreamableContentMemoryUsage();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nStreamableContentMemoryUsage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const SStreamAbleObject& rOther) const
|
||||
{
|
||||
return m_pObj == rOther.m_pObj;
|
||||
}
|
||||
|
||||
int GetStreamableContentMemoryUsage() const { return m_nStreamableContentMemoryUsage; }
|
||||
IStreamable* GetStreamAbleObject() const { return m_pObj; }
|
||||
uint32 GetLastDrawMainFrameId() const
|
||||
{
|
||||
return m_pObj->GetLastDrawMainFrameId();
|
||||
}
|
||||
float fCurImportance;
|
||||
private:
|
||||
IStreamable* m_pObj;
|
||||
int m_nStreamableContentMemoryUsage;
|
||||
};
|
||||
|
||||
struct SObjManPrecacheCamera
|
||||
{
|
||||
SObjManPrecacheCamera()
|
||||
: vPosition(ZERO)
|
||||
, vDirection(ZERO)
|
||||
, bbox(AABB::RESET)
|
||||
, fImportanceFactor(1.0f)
|
||||
{
|
||||
}
|
||||
|
||||
Vec3 vPosition;
|
||||
Vec3 vDirection;
|
||||
AABB bbox;
|
||||
float fImportanceFactor;
|
||||
};
|
||||
|
||||
struct SObjManPrecachePoint
|
||||
{
|
||||
SObjManPrecachePoint()
|
||||
: nId(0)
|
||||
{
|
||||
}
|
||||
|
||||
int nId;
|
||||
CTimeValue expireTime;
|
||||
};
|
||||
|
||||
struct IObjManager
|
||||
{
|
||||
virtual ~IObjManager() {}
|
||||
|
||||
virtual void PreloadLevelObjects() = 0;
|
||||
virtual void UnloadObjects(bool bDeleteAll) = 0;
|
||||
virtual void CheckTextureReadyFlag() = 0;
|
||||
virtual void FreeStatObj(IStatObj* pObj) = 0;
|
||||
virtual _smart_ptr<IStatObj> GetDefaultCGF() = 0;
|
||||
|
||||
typedef std::vector< IDecalRenderNode* > DecalsToPrecreate;
|
||||
virtual DecalsToPrecreate& GetDecalsToPrecreate() = 0;
|
||||
virtual PodArray<SStreamAbleObject>& GetArrStreamableObjects() = 0;
|
||||
virtual PodArray<SObjManPrecacheCamera>& GetStreamPreCacheCameras() = 0;
|
||||
virtual PodArray<COctreeNode*>& GetArrStreamingNodeStack() = 0;
|
||||
virtual PodArray<SObjManPrecachePoint>& GetStreamPreCachePointDefs() = 0;
|
||||
|
||||
typedef std::map<string, IStatObj*, stl::less_stricmp<string> > ObjectsMap;
|
||||
virtual ObjectsMap& GetNameToObjectMap() = 0;
|
||||
|
||||
typedef std::set<IStatObj*> LoadedObjects;
|
||||
virtual LoadedObjects& GetLoadedObjects() = 0;
|
||||
|
||||
virtual Vec3 GetSunColor() = 0;
|
||||
virtual void SetSunColor(const Vec3& color) = 0;
|
||||
|
||||
virtual Vec3 GetSunAnimColor() = 0;
|
||||
virtual void SetSunAnimColor(const Vec3& color) = 0;
|
||||
|
||||
virtual float GetSunAnimSpeed() = 0;
|
||||
virtual void SetSunAnimSpeed(float sunAnimSpeed) = 0;
|
||||
|
||||
virtual AZ::u8 GetSunAnimPhase() = 0;
|
||||
virtual void SetSunAnimPhase(AZ::u8 sunAnimPhase) = 0;
|
||||
|
||||
virtual AZ::u8 GetSunAnimIndex() = 0;
|
||||
virtual void SetSunAnimIndex(AZ::u8 sunAnimIndex) = 0;
|
||||
|
||||
virtual float GetSSAOAmount() = 0;
|
||||
virtual void SetSSAOAmount(float amount) = 0;
|
||||
|
||||
virtual float GetSSAOContrast() = 0;
|
||||
virtual void SetSSAOContrast(float amount) = 0;
|
||||
|
||||
virtual SRainParams& GetRainParams() = 0;
|
||||
virtual SSnowParams& GetSnowParams() = 0;
|
||||
|
||||
virtual bool IsCameraPrecacheOverridden() = 0;
|
||||
virtual void SetCameraPrecacheOverridden(bool state) = 0;
|
||||
|
||||
virtual IStatObj* LoadNewCGF(IStatObj* pObject, int flagCloth, bool bUseStreaming, bool bForceBreakable, unsigned long nLoadingFlags, const char* normalizedFilename, const void* pData, int nDataSize, const char* originalFilename, const char* geomName, IStatObj::SSubObject** ppSubObject) = 0;
|
||||
virtual IStatObj* LoadFromCacheNoRef(IStatObj* pObject, bool bUseStreaming, unsigned long nLoadingFlags, const char* geomName, IStatObj::SSubObject** ppSubObject) = 0;
|
||||
|
||||
virtual IStatObj* AllocateStatObj() = 0;
|
||||
virtual IStatObj* LoadStatObjUnsafeManualRef(const char* szFileName, const char* szGeomName = NULL, IStatObj::SSubObject** ppSubObject = NULL, bool bUseStreaming = true, unsigned long nLoadingFlags = 0, const void* m_pData = 0, int m_nDataSize = 0, const char* szBlockName = NULL) = 0;
|
||||
virtual _smart_ptr<IStatObj> LoadStatObjAutoRef(const char* szFileName, const char* szGeomName = NULL, IStatObj::SSubObject** ppSubObject = NULL, bool bUseStreaming = true, unsigned long nLoadingFlags = 0, const void* m_pData = 0, int m_nDataSize = 0, const char* szBlockName = NULL) = 0;
|
||||
virtual void GetLoadedStatObjArray(IStatObj** pObjectsArray, int& nCount) = 0;
|
||||
virtual bool InternalDeleteObject(IStatObj* pObject) = 0;
|
||||
virtual void MakeShadowCastersList(CVisArea* pReceiverArea, const AABB& aabbReceiver, int dwAllowedTypes, int32 nRenderNodeFlags, Vec3 vLightPos, CDLight* pLight, ShadowMapFrustum* pFr, PodArray<struct SPlaneObject>* pShadowHull, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual int MakeStaticShadowCastersList(IRenderNode* pIgnoreNode, ShadowMapFrustum* pFrustum, int renderNodeExcludeFlags, int nMaxNodes, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void MakeDepthCubemapRenderItemList(CVisArea* pReceiverArea, const AABB& cubemapAABB, int renderNodeFlags, PodArray<struct IShadowCaster*>* objectsList, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void PrecacheStatObjMaterial(_smart_ptr<IMaterial> pMaterial, const float fEntDistance, IStatObj* pStatObj, bool bFullUpdate, bool bDrawNear) = 0;
|
||||
virtual void PrecacheStatObj(IStatObj* pStatObj, int nLod, const Matrix34A& statObjMatrix, _smart_ptr<IMaterial> pMaterial, float fImportance, float fEntDistance, bool bFullUpdate, bool bHighPriority) = 0;
|
||||
|
||||
virtual int GetLoadedObjectCount() = 0;
|
||||
|
||||
virtual uint16 CheckCachedNearestCubeProbe(IRenderNode* pEnt) = 0;
|
||||
virtual int16 GetNearestCubeProbe(IVisArea* pVisArea, const AABB& objBox, bool bSpecular = true) = 0;
|
||||
|
||||
virtual void RenderObject(IRenderNode* o, const AABB& objBox, float fEntDistance, EERType eERType, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0;
|
||||
virtual void RenderDecalAndRoad(IRenderNode* pEnt, const AABB& objBox, float fEntDistance, bool nCheckOcclusion, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0;
|
||||
virtual void RenderObjectDebugInfo(IRenderNode* pEnt, float fEntDistance, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void RenderAllObjectDebugInfo() = 0;
|
||||
virtual void RenderObjectDebugInfo_Impl(IRenderNode* pEnt, float fEntDistance) = 0;
|
||||
virtual void RemoveFromRenderAllObjectDebugInfo(IRenderNode* pEnt) = 0;
|
||||
|
||||
virtual float GetXYRadius(int nType, int nSID = DEFAULT_SID) = 0;
|
||||
virtual bool GetStaticObjectBBox(int nType, Vec3& vBoxMin, Vec3& vBoxMax, int nSID = DEFAULT_SID) = 0;
|
||||
|
||||
virtual IStatObj* GetStaticObjectByTypeID(int nTypeID, int nSID = DEFAULT_SID) = 0;
|
||||
virtual IStatObj* FindStaticObjectByFilename(const char* filename) = 0;
|
||||
|
||||
//virtual float GetBendingRandomFactor() = 0;
|
||||
virtual float GetGSMMaxDistance() const = 0;
|
||||
virtual void SetGSMMaxDistance(float value) = 0;
|
||||
|
||||
virtual int GetUpdateStreamingPrioriryRoundIdFast() = 0;
|
||||
virtual int GetUpdateStreamingPrioriryRoundId() = 0;
|
||||
virtual void IncrementUpdateStreamingPrioriryRoundIdFast(int amount) = 0;
|
||||
virtual void IncrementUpdateStreamingPrioriryRoundId(int amount) = 0;
|
||||
|
||||
virtual NAsyncCull::CCullThread& GetCullThread() = 0;
|
||||
|
||||
virtual void SetLockCGFResources(bool state) = 0;
|
||||
virtual bool IsLockCGFResources() = 0;
|
||||
|
||||
virtual bool IsBoxOccluded(const AABB& objBox, float fDistance, OcclusionTestClient* const __restrict pOcclTestVars, bool bIndoorOccludersOnly, EOcclusionObjectType eOcclusionObjectType, const SRenderingPassInfo& passInfo) = 0;
|
||||
|
||||
virtual void AddDecalToRenderer(float fDistance, _smart_ptr<IMaterial> pMat, const uint8 sortPrio, Vec3 right, Vec3 up, const UCol& ucResCol, const uint8 uBlendType, const Vec3& vAmbientColor, Vec3 vPos, const int nAfterWater, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0;
|
||||
|
||||
virtual void RegisterForStreaming(IStreamable* pObj) = 0;
|
||||
virtual void UnregisterForStreaming(IStreamable* pObj) = 0;
|
||||
virtual void UpdateRenderNodeStreamingPriority(IRenderNode* pObj, float fEntDistance, float fImportanceFactor, bool bFullUpdate, const SRenderingPassInfo& passInfo, bool bHighPriority = false) = 0;
|
||||
|
||||
virtual void GetMemoryUsage(class ICrySizer* pSizer) const = 0;
|
||||
virtual void GetBandwidthStats(float* fBandwidthRequested) = 0;
|
||||
|
||||
virtual void ReregisterEntitiesInArea(Vec3 vBoxMin, Vec3 vBoxMax) = 0;
|
||||
virtual void UpdateObjectsStreamingPriority(bool bSyncLoad, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void ProcessObjectsStreaming(const SRenderingPassInfo& passInfo) = 0;
|
||||
|
||||
virtual void ProcessObjectsStreaming_Impl(bool bSyncLoad, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void ProcessObjectsStreaming_Sort(bool bSyncLoad, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void ProcessObjectsStreaming_Release() = 0;
|
||||
virtual void ProcessObjectsStreaming_InitLoad(bool bSyncLoad) = 0;
|
||||
virtual void ProcessObjectsStreaming_Finish() = 0;
|
||||
|
||||
// time counters
|
||||
virtual bool IsAfterWater(const Vec3& vPos, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void FreeNotUsedCGFs() = 0;
|
||||
virtual void MakeUnitCube() = 0;
|
||||
|
||||
virtual bool CheckOcclusion_TestAABB(const AABB& rAABB, float fEntDistance) = 0;
|
||||
virtual bool CheckOcclusion_TestQuad(const Vec3& vCenter, const Vec3& vAxisX, const Vec3& vAxisY) = 0;
|
||||
|
||||
virtual void PushIntoCullQueue(const SCheckOcclusionJobData& rCheckOcclusionData) = 0;
|
||||
virtual void PopFromCullQueue(SCheckOcclusionJobData* pCheckOcclusionData) = 0;
|
||||
|
||||
virtual void PushIntoCullOutputQueue(const SCheckOcclusionOutput& rCheckOcclusionOutput) = 0;
|
||||
virtual bool PopFromCullOutputQueue(SCheckOcclusionOutput* pCheckOcclusionOutput) = 0;
|
||||
|
||||
virtual void BeginCulling() = 0;
|
||||
virtual void RemoveCullJobProducer() = 0;
|
||||
virtual void AddCullJobProducer() = 0;
|
||||
|
||||
#ifndef _RELEASE
|
||||
virtual void CoverageBufferDebugDraw() = 0;
|
||||
#endif
|
||||
|
||||
virtual bool LoadOcclusionMesh(const char* pFileName) = 0;
|
||||
|
||||
virtual void ClearStatObjGarbage() = 0;
|
||||
virtual void CheckForGarbage(IStatObj* pObject) = 0;
|
||||
virtual void UnregisterForGarbage(IStatObj* pObject) = 0;
|
||||
|
||||
virtual int GetObjectLOD(const IRenderNode* pObj, float fDistance) = 0;
|
||||
virtual bool RayStatObjIntersection(IStatObj* pStatObj, const Matrix34& objMat, _smart_ptr<IMaterial> pMat, Vec3 vStart, Vec3 vEnd, Vec3& vClosestHitPoint, float& fClosestHitDistance, bool bFastTest) = 0;
|
||||
virtual bool RayRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const Vec3& vInDir, Vec3& vOutPos, Vec3& vOutNormal, bool bFastTest, _smart_ptr<IMaterial> pMat) = 0;
|
||||
virtual bool SphereRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const float fRadius, _smart_ptr<IMaterial> pMat) = 0;
|
||||
|
||||
virtual uint8 GetDissolveRef(float fDist, float fMaxViewDist) = 0;
|
||||
virtual float GetLodDistDissolveRef(SLodDistDissolveTransitionState* pState, float curDist, int nNewLod, const SRenderingPassInfo& passInfo) = 0;
|
||||
|
||||
virtual void CleanStreamingData() = 0;
|
||||
virtual IRenderMesh* GetRenderMeshBox() = 0;
|
||||
|
||||
virtual void PrepareCullbufferAsync(const CCamera& rCamera) = 0;
|
||||
virtual void BeginOcclusionCulling(const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void EndOcclusionCulling(bool waitForOcclusionJobCompletion = false) = 0;
|
||||
virtual void RenderBufferedRenderMeshes(const SRenderingPassInfo& passInfo) = 0;
|
||||
|
||||
virtual int GetListStaticTypesCount() = 0;
|
||||
virtual int GetListStaticTypesGroupCount(int typeId) = 0;
|
||||
virtual IStatInstGroup* GetIStatInstGroup(int typeId, int groupId) = 0;
|
||||
|
||||
virtual int IncrementNextPrecachePointId() = 0;
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_IPHYSICSDEBUGRENDERER_H
|
||||
#define CRYINCLUDE_CRYCOMMON_IPHYSICSDEBUGRENDERER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IPHYSICSDEBUGRENDERER_H
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_IPROXIMITYTRIGGERSYSTEM_H
|
||||
#define CRYINCLUDE_CRYCOMMON_IPROXIMITYTRIGGERSYSTEM_H
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/std/function/function_fwd.h>
|
||||
#include <Cry_Geo.h> // AABB
|
||||
|
||||
|
||||
/**
|
||||
* Represents a registered proximity trigger.
|
||||
*
|
||||
* Contains the id of the trigger, its bounds, and whether or not it's active.
|
||||
*/
|
||||
struct SProximityElement
|
||||
{
|
||||
AZ::EntityId id;
|
||||
AABB aabb;
|
||||
uint32 bActivated : 1;
|
||||
std::vector<SProximityElement*> inside;
|
||||
|
||||
using NarrowPassCheckFunction = AZStd::function<bool(const AZ::Vector3&)>;
|
||||
|
||||
// Can be used to do an optional narrow pass check on this proximity element
|
||||
NarrowPassCheckFunction m_narrowPassChecker;
|
||||
|
||||
SProximityElement()
|
||||
{
|
||||
id = AZ::EntityId(0);
|
||||
bActivated = 0;
|
||||
}
|
||||
~SProximityElement()
|
||||
{
|
||||
}
|
||||
bool AddInside(SProximityElement* elem)
|
||||
{
|
||||
// Sorted add.
|
||||
return stl::binary_insert_unique(inside, elem);
|
||||
}
|
||||
bool RemoveInside(SProximityElement* elem)
|
||||
{
|
||||
// sorted remove.
|
||||
return stl::binary_erase(inside, elem);
|
||||
}
|
||||
bool IsInside(SProximityElement* elem)
|
||||
{
|
||||
return std::binary_search(inside.begin(), inside.end(), elem);
|
||||
}
|
||||
|
||||
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{}
|
||||
};
|
||||
|
||||
/**
|
||||
* Bus for events dispatched by the proximity trigger system as triggered are
|
||||
* entered and exited by entities in the world.
|
||||
*/
|
||||
class ProximityTriggerEvents
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ebus Traits
|
||||
// ID'd on trigger entity Id
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
using BusIdType = AZ::EntityId;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual ~ProximityTriggerEvents() {}
|
||||
|
||||
/// Dispatched when an entity enters a trigger. The bus message is ID'd on the triggers entity Id.
|
||||
virtual void OnTriggerEnter(AZ::EntityId /*entityEntering*/) {};
|
||||
|
||||
/// Dispatched when an entity exits a trigger. The bus message is ID'd on the triggers entity Id.
|
||||
virtual void OnTriggerExit(AZ::EntityId /*entityExiting*/) {};
|
||||
};
|
||||
|
||||
using ProximityTriggerEventBus = AZ::EBus<ProximityTriggerEvents>;
|
||||
|
||||
/**
|
||||
* Bus for requests sent by components or game code to the proximity trigger system.
|
||||
*/
|
||||
class ProximityTriggerSystemRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides - proximity trigger system is a singleton
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual ~ProximityTriggerSystemRequests() {}
|
||||
|
||||
/// Creates a new trigger instance.
|
||||
virtual SProximityElement* CreateTrigger(SProximityElement::NarrowPassCheckFunction narrowPassChecker = nullptr) = 0;
|
||||
|
||||
/// Removes a trigger and queues it for deletion.
|
||||
virtual void RemoveTrigger(SProximityElement* pTrigger) = 0;
|
||||
|
||||
/// Moves a trigger in the world or redefines its dimensions.
|
||||
virtual void MoveTrigger(SProximityElement* pTrigger, const AABB& aabb, bool invalidateCachedAABB = false) = 0;
|
||||
|
||||
/// Creates a proxy in the world associated with an entity (Component or Legacy) for interacting with proximity trigger instances.
|
||||
virtual SProximityElement* CreateEntity(AZ::EntityId id) = 0;
|
||||
|
||||
/**
|
||||
* Set the entity's AABB to a unit AABB at the entity's world position if \aabb is empty, otherwise set the entity's AABB to \aabb
|
||||
* @param pEntity The pointer to a SProximityElment whose AABB needs to be updated
|
||||
* @param pos World position of the entity
|
||||
* @param aabb The new AABB in world space to set
|
||||
*/
|
||||
virtual void MoveEntity(SProximityElement* pEntity, const Vec3& pos, const AABB& aabb) = 0;
|
||||
|
||||
/// Removes an entity's proximity trigger proxy.
|
||||
virtual void RemoveEntity(SProximityElement* pEntity, bool instantEvent = false) = 0;
|
||||
};
|
||||
|
||||
using ProximityTriggerSystemRequestBus = AZ::EBus<ProximityTriggerSystemRequests>;
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IPROXIMITYTRIGGERSYSTEM_H
|
||||
@@ -16,7 +16,12 @@
|
||||
#include "Cry_Geo.h"
|
||||
#include "Cry_Camera.h"
|
||||
#include "ITexture.h"
|
||||
#include <IFuncVariable.h> // <> required for Interfuscator
|
||||
#include "Cry_Vector2.h"
|
||||
#include "Cry_Vector3.h"
|
||||
#include "Cry_Matrix33.h"
|
||||
#include "Cry_Color.h"
|
||||
#include "smartptr.h"
|
||||
#include "StringUtils.h"
|
||||
#include <IXml.h> // <> required for Interfuscator
|
||||
#include "smartptr.h"
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
@@ -99,7 +104,6 @@ struct ShadowFrustumMGPUCache;
|
||||
struct IAsyncTextureCompileListener;
|
||||
struct IClipVolume;
|
||||
struct SClipVolumeBlendInfo;
|
||||
class IImageFile;
|
||||
class CRenderView;
|
||||
struct SDynTexture2;
|
||||
class CTexture;
|
||||
@@ -693,7 +697,6 @@ public:
|
||||
#include <IShader.h> // <> required for Interfuscator
|
||||
//DOC-IGNORE-END
|
||||
#include <IRenderMesh.h>
|
||||
#include "IMeshBaking.h"
|
||||
|
||||
// Flags passed in function FreeResources.
|
||||
#define FRR_SHADERS 1
|
||||
@@ -1051,11 +1054,6 @@ namespace AZ {
|
||||
namespace Vertex {
|
||||
class Format;
|
||||
}
|
||||
namespace VideoRenderer
|
||||
{
|
||||
struct IVideoRenderer;
|
||||
struct DrawArguments;
|
||||
}
|
||||
}
|
||||
enum eRenderPrimitiveType : int8;
|
||||
enum RenderIndexType : int;
|
||||
@@ -1464,7 +1462,6 @@ struct IRenderer
|
||||
// Is threadsafe
|
||||
virtual bool EF_ReloadFile_Request (const char* szFileName) = 0;
|
||||
|
||||
virtual _smart_ptr<IImageFile> EF_LoadImage(const char* szFileName, uint32 nFlags) = 0;
|
||||
// Summary:
|
||||
// Remaps shader gen mask to common global mask.
|
||||
virtual uint64 EF_GetRemapedShaderMaskGen(const char* name, uint64 nMaskGen = 0, bool bFixup = 0) = 0;
|
||||
@@ -1739,8 +1736,6 @@ struct IRenderer
|
||||
virtual void RemoveTexture(unsigned int TextureId) = 0;
|
||||
virtual void DeleteFont(IFFont* font) = 0;
|
||||
|
||||
virtual bool BakeMesh(const SMeshBakingInputParams* pInputParams, SMeshBakingOutput* pReturnValues) = 0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This routines uses 2 destination surfaces. It triggers a backbuffer copy to one of its surfaces,
|
||||
// and then copies the other surface to system memory. This hopefully will remove any
|
||||
@@ -2346,11 +2341,6 @@ struct IRenderer
|
||||
virtual void EndProfilerSection(const char* name) = 0;
|
||||
virtual void AddProfilerLabel(const char* name) = 0;
|
||||
|
||||
// Video Renderer interface
|
||||
virtual void InitializeVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer) = 0;
|
||||
virtual void CleanupVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer) = 0;
|
||||
virtual void DrawVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer, const AZ::VideoRenderer::DrawArguments& drawArguments) = 0;
|
||||
|
||||
private:
|
||||
// use private for EF_Query to prevent client code to submit arbitrary combinations of output data/size
|
||||
virtual void EF_QueryImpl(ERenderQueryTypes eQuery, void* pInOut0, uint32 nInOutSize0, void* pInOut1, uint32 nInOutSize1) = 0;
|
||||
|
||||
@@ -24,7 +24,12 @@
|
||||
#endif
|
||||
|
||||
#include "smartptr.h"
|
||||
#include <IFuncVariable.h> // <> required for Interfuscator
|
||||
#include "Cry_Vector2.h"
|
||||
#include "Cry_Vector3.h"
|
||||
#include "Cry_Matrix33.h"
|
||||
#include "Cry_Color.h"
|
||||
#include "smartptr.h"
|
||||
#include "StringUtils.h"
|
||||
#include <IXml.h> // <> required for Interfuscator
|
||||
#include "smartptr.h"
|
||||
#include "VertexFormats.h"
|
||||
@@ -767,7 +772,6 @@ _MS_ALIGN(16) struct SSkinningData
|
||||
void* pCharInstCB; // used if per char instance cbs are available in renderdll (d3d11+);
|
||||
// members below are for Software Skinning
|
||||
void* pCustomData; // client specific data, used for example for sw-skinning on animation side
|
||||
SSkinningData** pMasterSkinningDataList; // used by the SkinningData for a Character Instance, contains a list of all Skin Instances which need SW-Skinning
|
||||
SSkinningData* pNextSkinningData; // List to the next element which needs SW-Skinning
|
||||
} _ALIGN(16);
|
||||
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <IShader.h> // <> required for Interfuscator
|
||||
|
||||
// Traits
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#include AZ_RESTRICTED_FILE(IShader_info_h)
|
||||
#elif !defined(LINUX) && !defined(APPLE)
|
||||
#define ISHADER_INFO_H_TRAIT_DEFINE_ETEX_INFO 1
|
||||
#endif
|
||||
|
||||
#if ISHADER_INFO_H_TRAIT_DEFINE_ETEX_INFO
|
||||
ENUM_INFO_BEGIN(ETEX_Format)
|
||||
ENUM_ELEM_INFO(, eTF_Unknown)
|
||||
ENUM_ELEM_INFO(, eTF_R8G8B8A8S)
|
||||
ENUM_ELEM_INFO(, eTF_R8G8B8A8)
|
||||
ENUM_ELEM_INFO(, eTF_A8)
|
||||
ENUM_ELEM_INFO(, eTF_R8)
|
||||
ENUM_ELEM_INFO(, eTF_R8S)
|
||||
ENUM_ELEM_INFO(, eTF_R16)
|
||||
ENUM_ELEM_INFO(, eTF_R16F)
|
||||
ENUM_ELEM_INFO(, eTF_R32F)
|
||||
ENUM_ELEM_INFO(, eTF_R8G8)
|
||||
ENUM_ELEM_INFO(, eTF_R8G8S)
|
||||
ENUM_ELEM_INFO(, eTF_R16G16)
|
||||
ENUM_ELEM_INFO(, eTF_R16G16S)
|
||||
ENUM_ELEM_INFO(, eTF_R16G16F)
|
||||
ENUM_ELEM_INFO(, eTF_R11G11B10F)
|
||||
ENUM_ELEM_INFO(, eTF_R10G10B10A2)
|
||||
ENUM_ELEM_INFO(, eTF_R16G16B16A16)
|
||||
ENUM_ELEM_INFO(, eTF_R16G16B16A16S)
|
||||
ENUM_ELEM_INFO(, eTF_R16G16B16A16F)
|
||||
ENUM_ELEM_INFO(, eTF_R32G32B32A32F)
|
||||
ENUM_ELEM_INFO(, eTF_CTX1)
|
||||
ENUM_ELEM_INFO(, eTF_BC1)
|
||||
ENUM_ELEM_INFO(, eTF_BC2)
|
||||
ENUM_ELEM_INFO(, eTF_BC3)
|
||||
ENUM_ELEM_INFO(, eTF_BC4U)
|
||||
ENUM_ELEM_INFO(, eTF_BC4S)
|
||||
ENUM_ELEM_INFO(, eTF_BC5U)
|
||||
ENUM_ELEM_INFO(, eTF_BC5S)
|
||||
ENUM_ELEM_INFO(, eTF_BC6UH)
|
||||
ENUM_ELEM_INFO(, eTF_BC6SH)
|
||||
ENUM_ELEM_INFO(, eTF_BC7)
|
||||
ENUM_ELEM_INFO(, eTF_R9G9B9E5)
|
||||
ENUM_ELEM_INFO(, eTF_D16)
|
||||
ENUM_ELEM_INFO(, eTF_D24S8)
|
||||
ENUM_ELEM_INFO(, eTF_D32F)
|
||||
ENUM_ELEM_INFO(, eTF_D32FS8)
|
||||
ENUM_ELEM_INFO(, eTF_B5G6R5)
|
||||
ENUM_ELEM_INFO(, eTF_B5G5R5)
|
||||
ENUM_ELEM_INFO(, eTF_B4G4R4A4)
|
||||
ENUM_ELEM_INFO(, eTF_EAC_R11)
|
||||
ENUM_ELEM_INFO(, eTF_EAC_RG11)
|
||||
ENUM_ELEM_INFO(, eTF_ETC2)
|
||||
ENUM_ELEM_INFO(, eTF_ETC2A)
|
||||
ENUM_ELEM_INFO(, eTF_A8L8)
|
||||
ENUM_ELEM_INFO(, eTF_L8)
|
||||
ENUM_ELEM_INFO(, eTF_L8V8U8)
|
||||
ENUM_ELEM_INFO(, eTF_B8G8R8)
|
||||
ENUM_ELEM_INFO(, eTF_L8V8U8X8)
|
||||
ENUM_ELEM_INFO(, eTF_B8G8R8X8)
|
||||
ENUM_ELEM_INFO(, eTF_B8G8R8A8)
|
||||
ENUM_INFO_END(ETEX_Format)
|
||||
#endif
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ITexture.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
// General purpose video 'rendering' solution that abstracts video data into textures
|
||||
// and data to update those textures with.
|
||||
namespace VideoRenderer
|
||||
{
|
||||
enum Constants
|
||||
{
|
||||
MaxInputTextureCount = 4,
|
||||
};
|
||||
|
||||
struct VideoTextureDesc
|
||||
{
|
||||
CryFixedStringT<64> m_name; // fixed string to avoid dll string copying issues
|
||||
uint32 m_width{ 4 };
|
||||
uint32 m_height{ 4 };
|
||||
ETEX_Format m_format{ eTF_Unknown };
|
||||
uint32 m_used{ 0 };
|
||||
};
|
||||
|
||||
// Full description of video texture resources for the renderer to create.
|
||||
struct VideoTexturesDesc
|
||||
{
|
||||
VideoTextureDesc m_outputTextureDesc;
|
||||
VideoTextureDesc m_inputTextureDescs[MaxInputTextureCount];
|
||||
};
|
||||
|
||||
// Full set of textures created from the VideoTexturesDesc provided to the renderer.
|
||||
struct VideoTextures
|
||||
{
|
||||
uint32 m_outputTextureId{ 0 };
|
||||
uint32 m_inputTextureIds[MaxInputTextureCount]{ 0 };
|
||||
};
|
||||
|
||||
struct VideoUpdateData
|
||||
{
|
||||
struct VideoTextureUpdateData
|
||||
{
|
||||
// Data to update the texture with, can be null.
|
||||
const void* m_data{ nullptr };
|
||||
|
||||
// Format of above data, required for format conversions if needed.
|
||||
ETEX_Format m_dataFormat{ eTF_Unknown };
|
||||
}
|
||||
m_inputTextureData[MaxInputTextureCount];
|
||||
};
|
||||
|
||||
// Set of data to update and render a frame of video textures.
|
||||
// Everything should be passed through by value except for the update data, which should be double buffered at the source.
|
||||
struct DrawArguments
|
||||
{
|
||||
// Set of textures to draw with.
|
||||
VideoTextures m_textures;
|
||||
|
||||
// Set of data to update the above textures with if set.
|
||||
VideoUpdateData m_updateData;
|
||||
|
||||
// Flag to indicate that we want to draw to the backbuffer.
|
||||
uint32 m_drawingToBackbuffer{ 0 };
|
||||
|
||||
// Payload information for reference. Useful for debugging.
|
||||
uint32 m_frameReference{ 0 };
|
||||
|
||||
// Scale applied to each texture.
|
||||
Vec4 m_textureScales[MaxInputTextureCount]{};
|
||||
|
||||
// Value added to final composited texture.
|
||||
Vec4 m_colorAdjustment{ ZERO };
|
||||
};
|
||||
|
||||
// Video Rendering interface to provide callbacks from the Render Thread
|
||||
struct IVideoRenderer
|
||||
{
|
||||
// Called from the Render Thread to request the description of the video textures.
|
||||
virtual bool GetVideoTexturesDesc(AZ::VideoRenderer::VideoTexturesDesc& videoTexturesDesc) const = 0;
|
||||
// Called from the Render Thread to get the set of video textures that were previously created. Used at cleanup time.
|
||||
virtual bool GetVideoTextures(AZ::VideoRenderer::VideoTextures& videoTextures) const = 0;
|
||||
|
||||
// Called from the Render Thread to provide the video textures it created from the VideoTexturesDesc.
|
||||
virtual bool NotifyTexturesCreated(const AZ::VideoRenderer::VideoTextures& videoTextures) = 0;
|
||||
// CAlled from the Render Thread to notify the video manager that its textures were destroyed.
|
||||
virtual bool NotifyTexturesDestroyed() = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,310 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Helper to enable inplace construction and destruction of objects
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_INPLACEFACTORY_H
|
||||
#define CRYINCLUDE_CRYCOMMON_INPLACEFACTORY_H
|
||||
#pragma once
|
||||
|
||||
|
||||
// Inspired by the boost inplace/typed_inplace factory, written by
|
||||
// Fernando Luis Cacciola Carballal and Tobias Schwinger
|
||||
//
|
||||
// See
|
||||
// http://www.boost.org/doc/libs/1_42_0/libs/utility/in_place_factories.html
|
||||
// for a detailed description
|
||||
//
|
||||
|
||||
class CInplaceFactory0
|
||||
{
|
||||
public:
|
||||
|
||||
explicit CInplaceFactory0()
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address) const
|
||||
{
|
||||
return new(address) T();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address, std::size_t n) const
|
||||
{
|
||||
for (char* next = address = this->template apply<T>(address); !!--n; )
|
||||
{
|
||||
this->template apply<T>(next = next + sizeof(T));
|
||||
}
|
||||
return address;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename Arg0 >
|
||||
class CInplaceFactory1
|
||||
{
|
||||
Arg0& m_Arg0;
|
||||
|
||||
public:
|
||||
|
||||
explicit CInplaceFactory1(Arg0& arg)
|
||||
: m_Arg0(arg)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address) const
|
||||
{
|
||||
return new(address) T(m_Arg0);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address, std::size_t n) const
|
||||
{
|
||||
for (char* next = address = this->template apply<T>(address); !!--n; )
|
||||
{
|
||||
this->template apply<T>(next = next + sizeof(T));
|
||||
}
|
||||
return address;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1
|
||||
>
|
||||
class CInplaceFactory2
|
||||
{
|
||||
Arg0& m_Arg0;
|
||||
Arg1& m_Arg1;
|
||||
|
||||
public:
|
||||
|
||||
explicit CInplaceFactory2(Arg0& arg0, Arg1& arg1)
|
||||
: m_Arg0(arg0)
|
||||
, m_Arg1(arg1)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address) const
|
||||
{
|
||||
return new(address) T(
|
||||
m_Arg0,
|
||||
m_Arg1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address, std::size_t n) const
|
||||
{
|
||||
for (char* next = address = this->template apply<T>(address); !!--n; )
|
||||
{
|
||||
this->template apply<T>(next = next + sizeof(T));
|
||||
}
|
||||
return address;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1,
|
||||
typename Arg2
|
||||
>
|
||||
class CInplaceFactory3
|
||||
{
|
||||
Arg0& m_Arg0;
|
||||
Arg1& m_Arg1;
|
||||
Arg2& m_Arg2;
|
||||
|
||||
public:
|
||||
|
||||
explicit CInplaceFactory3(Arg0& arg0, Arg1& arg1, Arg2& arg2)
|
||||
: m_Arg0(arg0)
|
||||
, m_Arg1(arg1)
|
||||
, m_Arg2(arg2)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address) const
|
||||
{
|
||||
return new(address) T(
|
||||
m_Arg0,
|
||||
m_Arg1,
|
||||
m_Arg2);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address, std::size_t n) const
|
||||
{
|
||||
for (char* next = address = this->template apply<T>(address); !!--n; )
|
||||
{
|
||||
this->template apply<T>(next = next + sizeof(T));
|
||||
}
|
||||
return address;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1,
|
||||
typename Arg2,
|
||||
typename Arg3
|
||||
>
|
||||
class CInplaceFactory4
|
||||
{
|
||||
Arg0& m_Arg0;
|
||||
Arg1& m_Arg1;
|
||||
Arg2& m_Arg2;
|
||||
Arg3& m_Arg3;
|
||||
|
||||
public:
|
||||
|
||||
explicit CInplaceFactory4(Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3)
|
||||
: m_Arg0(arg0)
|
||||
, m_Arg1(arg1)
|
||||
, m_Arg2(arg2)
|
||||
, m_Arg3(arg3)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address) const
|
||||
{
|
||||
return new(address) T(
|
||||
m_Arg0,
|
||||
m_Arg1,
|
||||
m_Arg2,
|
||||
m_Arg3);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address, std::size_t n) const
|
||||
{
|
||||
for (char* next = address = this->template apply<T>(address); !!--n; )
|
||||
{
|
||||
this->template apply<T>(next = next + sizeof(T));
|
||||
}
|
||||
return address;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1,
|
||||
typename Arg2,
|
||||
typename Arg3,
|
||||
typename Arg4
|
||||
>
|
||||
class CInplaceFactory5
|
||||
{
|
||||
Arg0& m_Arg0;
|
||||
Arg1& m_Arg1;
|
||||
Arg2& m_Arg2;
|
||||
Arg3& m_Arg3;
|
||||
Arg4& m_Arg4;
|
||||
|
||||
public:
|
||||
|
||||
explicit CInplaceFactory5(Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3, Arg4& arg4)
|
||||
: m_Arg0(arg0)
|
||||
, m_Arg1(arg1)
|
||||
, m_Arg2(arg2)
|
||||
, m_Arg3(arg3)
|
||||
, m_Arg4(arg4)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address) const
|
||||
{
|
||||
return new(address) T(
|
||||
m_Arg0,
|
||||
m_Arg1,
|
||||
m_Arg2,
|
||||
m_Arg3,
|
||||
m_Arg4);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address, std::size_t n) const
|
||||
{
|
||||
for (char* next = address = this->template apply<T>(address); !!--n; )
|
||||
{
|
||||
this->template apply<T>(next = next + sizeof(T));
|
||||
}
|
||||
return address;
|
||||
}
|
||||
};
|
||||
|
||||
inline CInplaceFactory0 InplaceFactory()
|
||||
{
|
||||
return CInplaceFactory0();
|
||||
}
|
||||
|
||||
template < typename Arg0 >
|
||||
inline CInplaceFactory1<Arg0> InplaceFactory(Arg0& arg0)
|
||||
{
|
||||
return CInplaceFactory1<Arg0>(arg0);
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1
|
||||
|
||||
>
|
||||
inline CInplaceFactory2<Arg0, Arg1> InplaceFactory(Arg0& arg0, Arg1& arg1)
|
||||
{
|
||||
return CInplaceFactory2<Arg0, Arg1>(arg0, arg1);
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1,
|
||||
typename Arg2
|
||||
>
|
||||
inline CInplaceFactory3<Arg0, Arg1, Arg2> InplaceFactory(Arg0& arg0, Arg1& arg1, Arg2& arg2)
|
||||
{
|
||||
return CInplaceFactory3<Arg0, Arg1, Arg2> (arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1,
|
||||
typename Arg2,
|
||||
typename Arg3
|
||||
>
|
||||
inline CInplaceFactory4<Arg0, Arg1, Arg2, Arg3> InplaceFactory(
|
||||
Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3)
|
||||
{
|
||||
return CInplaceFactory4<Arg0, Arg1, Arg2, Arg3>(arg0, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1,
|
||||
typename Arg2,
|
||||
typename Arg3,
|
||||
typename Arg4
|
||||
>
|
||||
inline CInplaceFactory5<Arg0, Arg1, Arg2, Arg3, Arg4> InplaceFactory(
|
||||
Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3, Arg4& arg4)
|
||||
{
|
||||
return CInplaceFactory5<Arg0, Arg1, Arg2, Arg3, Arg4>(arg0, arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_INPLACEFACTORY_H
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_MATERIALUTILS_H
|
||||
#define CRYINCLUDE_CRYCOMMON_MATERIALUTILS_H
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/IO/SystemFile.h> // for max path len
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
#include <ISystem.h>
|
||||
|
||||
namespace MaterialUtils
|
||||
{
|
||||
//! UnifyMaterialName - given a non-unified material name, remove the extension, unify the slashes
|
||||
//! and fix up any legacy naming issues so that the material name can be used in a hash map
|
||||
//! and will work each lookup.
|
||||
inline void UnifyMaterialName(char* inputOutputBuffer)
|
||||
{
|
||||
if (!inputOutputBuffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// convert slashes and remove extensions:
|
||||
size_t inputLength = strlen(inputOutputBuffer);
|
||||
if (inputLength == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// this must be done first, so that the extension cutting function below does not mistakenly destroy this when it finds the .
|
||||
if ((azstrnicmp(inputOutputBuffer, "./", 2) == 0) || (azstrnicmp(inputOutputBuffer, ".\\", 2) == 0))
|
||||
{
|
||||
memmove(inputOutputBuffer, inputOutputBuffer + 2, inputLength - 2);
|
||||
inputOutputBuffer[inputLength - 2] = 0;
|
||||
inputLength -= 2;
|
||||
}
|
||||
|
||||
for (size_t pos = 0; pos < inputLength; ++pos)
|
||||
{
|
||||
if (inputOutputBuffer[pos] == '\\')
|
||||
{
|
||||
inputOutputBuffer[pos] = '/'; // unify slashes
|
||||
}
|
||||
else
|
||||
{
|
||||
inputOutputBuffer[pos] = tolower(inputOutputBuffer[pos]);
|
||||
}
|
||||
}
|
||||
AZStd::string tempString(inputOutputBuffer);
|
||||
AzFramework::StringFunc::Path::StripExtension(tempString);
|
||||
|
||||
AZ_Assert(tempString.length() <= inputLength, "Extension stripped string has to be smaller than/same size as original string!");
|
||||
// real size of inputOutputBuffer is inputLength + 1 with Null character
|
||||
azstrcpy(inputOutputBuffer, inputLength + 1, tempString.c_str());
|
||||
#if defined(SUPPORT_LEGACY_MATERIAL_NAMES)
|
||||
|
||||
// LEGACY support Some files may start with ./ in front of them. This is not required anymore.
|
||||
static const char* removals[2] = {
|
||||
"engine/",
|
||||
nullptr // reserved for game name
|
||||
};
|
||||
static size_t removalSize = sizeof(removals) / sizeof(removals[0]);
|
||||
|
||||
// LEGACY support. Some files may start with gamename in front of them. This is not required anymore.
|
||||
static char cachedGameName[AZ_MAX_PATH_LEN] = { 0 };
|
||||
if (!removals[removalSize - 1])
|
||||
{
|
||||
auto projectName = AZ::Utils::GetProjectName();
|
||||
if (!projectName.empty())
|
||||
{
|
||||
azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, projectName.c_str());
|
||||
azstrcat(cachedGameName, AZ_MAX_PATH_LEN, "/");
|
||||
}
|
||||
|
||||
if (cachedGameName[0] == 0)
|
||||
{
|
||||
// at least substitute something so that unit tests can make this assumption:
|
||||
azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, "AutomatedTesting/");
|
||||
}
|
||||
|
||||
removals[removalSize - 1] = cachedGameName;
|
||||
}
|
||||
|
||||
for (size_t pos = 0; pos < removalSize; ++pos)
|
||||
{
|
||||
if (removals[pos])
|
||||
{
|
||||
size_t removalLength = strlen(removals[pos]);
|
||||
if (removalLength >= inputLength)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (azstrnicmp(inputOutputBuffer, removals[pos], removalLength) == 0)
|
||||
{
|
||||
memmove(inputOutputBuffer, inputOutputBuffer + removalLength, inputLength - removalLength);
|
||||
inputOutputBuffer[inputLength - removalLength] = 0;
|
||||
inputLength -= removalLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// legacy: Files were saved into a mtl with many leading forward or back slashes, we eat them all here. We want it to start with a rel path.
|
||||
const char* actualFileName = inputOutputBuffer;
|
||||
size_t finalLength = inputLength;
|
||||
while ((actualFileName[0]) && ((actualFileName[0] == '\\') || (actualFileName[0] == '/')))
|
||||
{
|
||||
++actualFileName;
|
||||
--finalLength;
|
||||
}
|
||||
if (finalLength != inputLength)
|
||||
{
|
||||
memmove(inputOutputBuffer, actualFileName, finalLength);
|
||||
inputOutputBuffer[finalLength] = 0;
|
||||
inputLength = finalLength;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_MATERIALUTILS_H
|
||||
@@ -12,8 +12,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <IRenderer.h>
|
||||
#include <IVideoRenderer.h>
|
||||
#include <IImage.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
struct SRendItemSorter {};
|
||||
@@ -294,8 +292,6 @@ public:
|
||||
bool(const char* szFileName));
|
||||
MOCK_METHOD1(EF_ReloadFile_Request,
|
||||
bool(const char* szFileName));
|
||||
MOCK_METHOD2(EF_LoadImage,
|
||||
_smart_ptr<IImageFile>(const char* szFileName, uint32 nFlags));
|
||||
MOCK_METHOD3(EF_GetRemapedShaderMaskGen,
|
||||
uint64(const char*, uint64, bool));
|
||||
MOCK_METHOD3(EF_GetShaderGlobalMaskGenFromString,
|
||||
@@ -533,8 +529,6 @@ public:
|
||||
void(unsigned int TextureId));
|
||||
MOCK_METHOD1(DeleteFont,
|
||||
void(IFFont * font));
|
||||
MOCK_METHOD2(BakeMesh,
|
||||
bool(const SMeshBakingInputParams * pInputParams, SMeshBakingOutput * pReturnValues));
|
||||
MOCK_METHOD3(CaptureFrameBufferFast,
|
||||
bool(unsigned char* pDstRGBA8, int destinationWidth, int destinationHeight));
|
||||
MOCK_METHOD3(CopyFrameBufferFast,
|
||||
@@ -857,13 +851,6 @@ public:
|
||||
MOCK_METHOD1(AddProfilerLabel,
|
||||
void(const char*));
|
||||
|
||||
MOCK_METHOD1(InitializeVideoRenderer,
|
||||
void(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer));
|
||||
MOCK_METHOD1(CleanupVideoRenderer,
|
||||
void(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer));
|
||||
MOCK_METHOD2(DrawVideoRenderer,
|
||||
void(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer, const AZ::VideoRenderer::DrawArguments& drawArguments));
|
||||
|
||||
MOCK_METHOD5(EF_QueryImpl,
|
||||
void(ERenderQueryTypes eQuery, void* pInOut0, uint32 nInOutSize0, void* pInOut1, uint32 nInOutSize1));
|
||||
};
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_NAME_TYPEINFO_H
|
||||
#define CRYINCLUDE_CRYCOMMON_NAME_TYPEINFO_H
|
||||
#pragma once
|
||||
|
||||
#include "CryName.h"
|
||||
|
||||
// CCryName TypeInfo
|
||||
|
||||
TYPE_INFO_BASIC(CCryName)
|
||||
|
||||
string ToString(CCryName const& val)
|
||||
{
|
||||
return string(val.c_str());
|
||||
}
|
||||
bool FromString(CCryName& val, const char* s)
|
||||
{
|
||||
val = s;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_NAME_TYPEINFO_H
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include <AzCore/Math/Color.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
|
||||
// Water level unknown.
|
||||
#define WATER_LEVEL_UNKNOWN -1000000.f
|
||||
#define BOTTOM_LEVEL_UNKNOWN -1000000.f
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
/**
|
||||
* Numeric constants that the editors should use for the ocean properties
|
||||
*/
|
||||
namespace OceanConstants
|
||||
{
|
||||
// Ocean Height consts are maintained for backwards compatibility
|
||||
// @TODO: Remove height / depth related consts when feature toggle is removed.
|
||||
static const float s_HeightMin = -AZ::Constants::MaxFloatBeforePrecisionLoss;
|
||||
static const float s_HeightMax = AZ::Constants::MaxFloatBeforePrecisionLoss;
|
||||
static const float s_HeightUnknown = WATER_LEVEL_UNKNOWN;
|
||||
static const float s_BottomUnknown = BOTTOM_LEVEL_UNKNOWN;
|
||||
static const float s_DefaultHeight = 16.0f;
|
||||
|
||||
static const float s_CausticsDistanceAttenMin = 0.0f;
|
||||
static const float s_CausticsDistanceAttenDefault = 10.0f;
|
||||
static const float s_CausticsDistanceAttenMax = 100.0f;
|
||||
static const float s_CausticsDepthMin = 0.0f;
|
||||
static const float s_CausticsDepthDefault = 8.0f;
|
||||
static const float s_CausticsDepthMax = 100.0f;
|
||||
static const float s_CausticsIntensityMin = 0.0f;
|
||||
static const float s_CausticsIntensityDefault = 1.0f;
|
||||
static const float s_CausticsIntensityMax = 10.0f;
|
||||
static const float s_CausticsTilingMin = 0.10f;
|
||||
static const float s_CausticsTilingDefault = 2.0f;
|
||||
static const float s_CausticsTilingMax = 10.0f;
|
||||
|
||||
static const float s_animationWavesAmountMin = 0.2f;
|
||||
static const float s_animationWavesAmountMax = 5.0f;
|
||||
static const float s_animationWavesAmountDefault = 0.75f;
|
||||
static const float s_animationWavesSizeMin = 0.0f;
|
||||
static const float s_animationWavesSizeMax = 3.0f;
|
||||
static const float s_animationWavesSizeDefault = 1.25f;
|
||||
static const float s_animationWavesSpeedMin = 0.0f;
|
||||
static const float s_animationWavesSpeedMax = 5.0f;
|
||||
static const float s_animationWavesSpeedDefault = 1.0f;
|
||||
static const float s_animationWindDirectionMin = 0.0f;
|
||||
static const float s_animationWindDirectionMax = 6.2832f;
|
||||
static const float s_animationWindDirectionDefault = 1;
|
||||
static const float s_animationWindSpeedMin = 0.0f;
|
||||
static const float s_animationWindSpeedMax = 1000.0f;
|
||||
static const float s_animationWindSpeedDefault = 40.0f;
|
||||
|
||||
static const AZ::Color s_oceanFogColorDefault((AZ::u8)5, (AZ::u8)36, (AZ::u8)32, (AZ::u8)255);
|
||||
static const AZ::Color s_oceanNearFogColorDefault((AZ::u8)1, (AZ::u8)7, (AZ::u8)5, (AZ::u8)255);
|
||||
static const float s_oceanFogColorMultiplierDefault = 0.15f;
|
||||
static const float s_oceanFogDensityDefault = 0.07f;
|
||||
static const float s_OceanFogColorMultiplierMin = 0.0f;
|
||||
static const float s_OceanFogColorMultiplierMax = 1.0f;
|
||||
static const float s_OceanFogDensityMin = 0.0f;
|
||||
static const float s_OceanFogDensityMax = 1.0f;
|
||||
|
||||
static const int s_waterTessellationAmountMin = 10;
|
||||
static const int s_waterTessellationAmountMax = 500;
|
||||
static const int s_waterTessellationDefault = 85;
|
||||
|
||||
static const bool s_UseOceanBottom = true;
|
||||
|
||||
static const bool s_GodRaysEnabled = true;
|
||||
static const float s_UnderwaterDistortion = 1.0f;
|
||||
|
||||
static const float s_oceanIsVeryFarAway = 1000000.f;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,363 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Archive/IArchive.h>
|
||||
|
||||
//! Everybody should use fxopen instead of fopen so it opens on all platforms
|
||||
inline AZ::IO::HandleType fxopen(const char* file, const char* mode, bool bGameRelativePath = false)
|
||||
{
|
||||
if (gEnv && gEnv->pCryPak)
|
||||
{
|
||||
gEnv->pCryPak->CheckFileAccessDisabled(file, mode);
|
||||
}
|
||||
bool bWriteAccess = false;
|
||||
for (const char* s = mode; *s; s++)
|
||||
{
|
||||
if (*s == 'w' || *s == 'W' || *s == 'a' || *s == 'A' || *s == '+')
|
||||
{
|
||||
bWriteAccess = true;
|
||||
break;
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
if (gEnv && gEnv->pCryPak)
|
||||
{
|
||||
int nAdjustFlags = 0;
|
||||
if (!bGameRelativePath)
|
||||
{
|
||||
nAdjustFlags |= AZ::IO::IArchive::FLAGS_PATH_REAL;
|
||||
}
|
||||
if (bWriteAccess)
|
||||
{
|
||||
nAdjustFlags |= AZ::IO::IArchive::FLAGS_FOR_WRITING;
|
||||
}
|
||||
char path[_MAX_PATH];
|
||||
const char* szAdjustedPath = gEnv->pCryPak->AdjustFileName(file, path, AZ_ARRAY_SIZE(path), nAdjustFlags);
|
||||
|
||||
#if !AZ_TRAIT_LEGACY_CRYPAK_UNIX_LIKE_FILE_SYSTEM
|
||||
if (bWriteAccess)
|
||||
{
|
||||
// Make sure folder is created.
|
||||
gEnv->pCryPak->MakeDir(szAdjustedPath);
|
||||
}
|
||||
#endif
|
||||
AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle;
|
||||
AZ::IO::FileIOBase::GetInstance()->Open(szAdjustedPath, AZ::IO::GetOpenModeFromStringMode(mode), fileHandle);
|
||||
return fileHandle;
|
||||
}
|
||||
else
|
||||
{
|
||||
return AZ::IO::InvalidHandle;
|
||||
}
|
||||
}
|
||||
|
||||
class CDebugAllowFileAccess
|
||||
{
|
||||
public:
|
||||
#if defined(_RELEASE)
|
||||
ILINE CDebugAllowFileAccess() { }
|
||||
ILINE void End() { }
|
||||
#else
|
||||
CDebugAllowFileAccess()
|
||||
{
|
||||
m_threadId = AZStd::this_thread::get_id();
|
||||
m_oldDisable = gEnv->pCryPak ? gEnv->pCryPak->DisableRuntimeFileAccess(false, m_threadId) : false;
|
||||
m_active = true;
|
||||
}
|
||||
~CDebugAllowFileAccess()
|
||||
{
|
||||
End();
|
||||
}
|
||||
void End()
|
||||
{
|
||||
if (m_active)
|
||||
{
|
||||
if (gEnv && gEnv->pCryPak)
|
||||
{
|
||||
gEnv->pCryPak->DisableRuntimeFileAccess(m_oldDisable, m_threadId);
|
||||
}
|
||||
m_active = false;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
AZStd::thread_id m_threadId;
|
||||
bool m_oldDisable;
|
||||
bool m_active;
|
||||
#endif
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class CInMemoryFileLoader
|
||||
{
|
||||
public:
|
||||
CInMemoryFileLoader(AZ::IO::IArchive* pCryPak)
|
||||
: m_pPak(pCryPak)
|
||||
, m_fileHandle(AZ::IO::InvalidHandle)
|
||||
, m_pBuffer(0)
|
||||
, m_pCursor(0)
|
||||
, m_nFileSize(0) {}
|
||||
~CInMemoryFileLoader()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool IsFileExists() const
|
||||
{
|
||||
return m_fileHandle != AZ::IO::InvalidHandle;
|
||||
}
|
||||
|
||||
AZ::IO::HandleType GetFileHandle() const
|
||||
{
|
||||
return m_fileHandle;
|
||||
}
|
||||
|
||||
bool FOpen(const char* name, const char* mode, bool bImmediateCloseFile = false)
|
||||
{
|
||||
if (m_pPak)
|
||||
{
|
||||
assert(m_fileHandle == AZ::IO::InvalidHandle);
|
||||
m_fileHandle = m_pPak->FOpen(name, mode);
|
||||
if (m_fileHandle == AZ::IO::InvalidHandle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nFileSize = m_pPak->FGetSize(m_fileHandle);
|
||||
if (m_nFileSize == 0)
|
||||
{
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pCursor = m_pBuffer = (char*)m_pPak->PoolMalloc(m_nFileSize);
|
||||
|
||||
size_t nReaded = m_pPak->FReadRawAll(m_pBuffer, m_nFileSize, m_fileHandle);
|
||||
if (nReaded != m_nFileSize)
|
||||
{
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bImmediateCloseFile)
|
||||
{
|
||||
m_pPak->FClose(m_fileHandle);
|
||||
m_fileHandle = AZ::IO::InvalidHandle;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FClose()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
size_t FReadRaw(void* data, size_t length, size_t elems)
|
||||
{
|
||||
ptrdiff_t dist = m_pCursor - m_pBuffer;
|
||||
|
||||
size_t count = length;
|
||||
if (dist + count * elems > m_nFileSize)
|
||||
{
|
||||
count = (m_nFileSize - dist) / elems;
|
||||
}
|
||||
|
||||
memmove(data, m_pCursor, count * elems);
|
||||
m_pCursor += count * elems;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
size_t FRead(T* data, size_t elems, bool bSwapEndian = eLittleEndian)
|
||||
{
|
||||
ptrdiff_t dist = m_pCursor - m_pBuffer;
|
||||
|
||||
size_t count = elems;
|
||||
if (dist + count * sizeof(T) > m_nFileSize)
|
||||
{
|
||||
count = (m_nFileSize - dist) / sizeof(T);
|
||||
}
|
||||
|
||||
memmove(data, m_pCursor, count * sizeof(T));
|
||||
m_pCursor += count * sizeof(T);
|
||||
|
||||
SwapEndian(data, count, bSwapEndian);
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t FTell()
|
||||
{
|
||||
ptrdiff_t dist = m_pCursor - m_pBuffer;
|
||||
return dist;
|
||||
}
|
||||
|
||||
int FSeek(int64_t origin, int command)
|
||||
{
|
||||
int retCode = -1;
|
||||
int64_t newPos;
|
||||
char* newPosBuf;
|
||||
switch (command)
|
||||
{
|
||||
case SEEK_SET:
|
||||
newPos = origin;
|
||||
if (newPos <= (int64_t)m_nFileSize)
|
||||
{
|
||||
m_pCursor = m_pBuffer + newPos;
|
||||
retCode = 0;
|
||||
}
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
newPosBuf = m_pCursor + origin;
|
||||
if (newPosBuf <= m_pBuffer + m_nFileSize)
|
||||
{
|
||||
m_pCursor = newPosBuf;
|
||||
retCode = 0;
|
||||
}
|
||||
break;
|
||||
case SEEK_END:
|
||||
newPos = m_nFileSize - origin;
|
||||
if (newPos <= (int64_t)m_nFileSize)
|
||||
{
|
||||
m_pCursor = m_pBuffer + newPos;
|
||||
retCode = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Not valid disk operation!
|
||||
AZ_Assert(false, "Invalid disk operation");
|
||||
}
|
||||
return retCode;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void Close()
|
||||
{
|
||||
if (m_fileHandle != AZ::IO::InvalidHandle)
|
||||
{
|
||||
m_pPak->FClose(m_fileHandle);
|
||||
}
|
||||
|
||||
if (m_pBuffer)
|
||||
{
|
||||
m_pPak->PoolFree(m_pBuffer);
|
||||
}
|
||||
|
||||
m_pBuffer = m_pCursor = 0;
|
||||
m_nFileSize = 0;
|
||||
m_fileHandle = AZ::IO::InvalidHandle;
|
||||
}
|
||||
|
||||
private:
|
||||
AZ::IO::HandleType m_fileHandle;
|
||||
char* m_pBuffer;
|
||||
AZ::IO::IArchive* m_pPak;
|
||||
char* m_pCursor;
|
||||
size_t m_nFileSize;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Helper class that can be used to recursively scan the directory.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct SDirectoryEnumeratorHelper
|
||||
{
|
||||
public:
|
||||
void ScanDirectoryRecursive(AZ::IO::IArchive* pIPak, const AZStd::string& root, const AZStd::string& pathIn, const AZStd::string& fileSpec, AZStd::vector<AZStd::string>& files)
|
||||
{
|
||||
auto AddSlash = [](AZStd::string_view path) -> AZStd::string
|
||||
{
|
||||
if (path.ends_with(AZ_CORRECT_DATABASE_SEPARATOR))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
else if (path.ends_with(AZ_WRONG_DATABASE_SEPARATOR))
|
||||
{
|
||||
return AZStd::string{ path.substr(0, path.size() - 1) } + AZ_CORRECT_DATABASE_SEPARATOR;
|
||||
}
|
||||
return path.empty() ? AZStd::string(path) : AZStd::string(path) + AZ_CORRECT_DATABASE_SEPARATOR;
|
||||
};
|
||||
AZStd::string dir;
|
||||
AZ::StringFunc::Path::Join(root.c_str(), pathIn.c_str(), dir);
|
||||
dir = AddSlash(dir);
|
||||
|
||||
ScanDirectoryFiles(pIPak, "", dir, fileSpec, files);
|
||||
|
||||
AZStd::string findFilter;
|
||||
AZ::StringFunc::Path::Join(dir.c_str(), "*", findFilter);
|
||||
|
||||
// Add all directories.
|
||||
|
||||
AZ::IO::ArchiveFileIterator pakFileIterator = pIPak->FindFirst(findFilter.c_str());
|
||||
if (pakFileIterator)
|
||||
{
|
||||
do
|
||||
{
|
||||
// Skip back folders.
|
||||
if (pakFileIterator.m_filename[0] == '.')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pakFileIterator.m_filename.empty())
|
||||
{
|
||||
AZ_Fatal("Archive", "IArchive FindFirst/FindNext returned empty name while looking for '%s'", findFilter.c_str());
|
||||
continue;
|
||||
}
|
||||
if ((pakFileIterator.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory) // skip sub directories.
|
||||
{
|
||||
AZStd::string scanDir = AZStd::string::format("%s%.*s/", AddSlash(pathIn).c_str(), aznumeric_cast<int>(pakFileIterator.m_filename.size()), pakFileIterator.m_filename.data());
|
||||
scanDir += AZ_CORRECT_DATABASE_SEPARATOR;
|
||||
ScanDirectoryRecursive(pIPak, root, scanDir, fileSpec, files);
|
||||
continue;
|
||||
}
|
||||
} while (pakFileIterator = pIPak->FindNext(pakFileIterator));
|
||||
pIPak->FindClose(pakFileIterator);
|
||||
}
|
||||
}
|
||||
private:
|
||||
void ScanDirectoryFiles(AZ::IO::IArchive* pIPak, const AZStd::string& root, const AZStd::string& path, const AZStd::string& fileSpec, AZStd::vector<AZStd::string>& files)
|
||||
{
|
||||
AZStd::string dir;
|
||||
AZ::StringFunc::Path::Join(root.c_str(), path.c_str(), dir);
|
||||
|
||||
AZStd::string findFilter;
|
||||
AZ::StringFunc::Path::Join(dir.c_str(), fileSpec.c_str(), findFilter);
|
||||
|
||||
AZ::IO::ArchiveFileIterator pakFileIterator = pIPak->FindFirst(findFilter.c_str());
|
||||
if (pakFileIterator)
|
||||
{
|
||||
do
|
||||
{
|
||||
// Skip back folders and subdirectories.
|
||||
if (pakFileIterator.m_filename[0] == '.' || (pakFileIterator.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
AZStd::string fullPath;
|
||||
AZ::StringFunc::Path::Join(path.c_str(), AZStd::string(pakFileIterator.m_filename).c_str(), fullPath);
|
||||
files.push_back(fullPath);
|
||||
} while (pakFileIterator = pIPak->FindNext(pakFileIterator));
|
||||
pIPak->FindClose(pakFileIterator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <CryCommon/PakLoadDataUtils.h>
|
||||
|
||||
namespace PakLoadDataUtils
|
||||
{
|
||||
bool LoadDataFromFile_Seek(size_t elems, AZ::IO::HandleType& fileHandle, int& nDataSize, [[maybe_unused]] EEndian eEndian)
|
||||
{
|
||||
GetISystem()->GetIPak()->FSeek(fileHandle, elems, SEEK_CUR);
|
||||
nDataSize -= elems;
|
||||
AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0");
|
||||
return (nDataSize >= 0);
|
||||
}
|
||||
|
||||
bool LoadDataFromFile_Seek(size_t elems, uint8*& f, int& nDataSize, [[maybe_unused]] EEndian eEndian)
|
||||
{
|
||||
nDataSize -= elems;
|
||||
f += elems;
|
||||
AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0");
|
||||
return true;
|
||||
}
|
||||
|
||||
void LoadDataFromFile_FixAlignment(AZ::IO::HandleType& fileHandle, int& nDataSize)
|
||||
{
|
||||
while (nDataSize & 3)
|
||||
{
|
||||
[[maybe_unused]] size_t nRes = GetISystem()->GetIPak()->FSeek(fileHandle, 1, SEEK_CUR);
|
||||
AZ_Assert(nRes == 0, "FSeek failed for 1 byte");
|
||||
AZ_Assert(nDataSize, "nDataSize reached zero" );
|
||||
nDataSize--;
|
||||
}
|
||||
AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0");
|
||||
}
|
||||
|
||||
void LoadDataFromFile_FixAlignment(uint8*& f, int& nDataSize)
|
||||
{
|
||||
while (nDataSize & 3)
|
||||
{
|
||||
AZ_Assert(*f == 222, "Found invalid data in buffer.");
|
||||
f++;
|
||||
AZ_Assert(nDataSize, "nDataSize reached zero");
|
||||
nDataSize--;
|
||||
}
|
||||
AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0");
|
||||
}
|
||||
|
||||
} //namespace PakLoadDataUtils
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <ISystem.h>
|
||||
#include <AzFramework/Archive/IArchive.h>
|
||||
|
||||
namespace PakLoadDataUtils
|
||||
{
|
||||
template <class T>
|
||||
static bool LoadDataFromFile(T* data, size_t elems, AZ::IO::HandleType& fileHandle, int& nDataSize, EEndian eEndian, int* pSeek = 0)
|
||||
{
|
||||
auto ipak = GetISystem()->GetIPak();
|
||||
if (pSeek)
|
||||
{
|
||||
*pSeek = aznumeric_cast<int>(ipak->FTell(fileHandle));
|
||||
}
|
||||
|
||||
if (ipak->FRead(data, elems, fileHandle, eEndian) != elems)
|
||||
{
|
||||
AZ_Assert(false, "Failed to read %zu elements", elems);
|
||||
return false;
|
||||
}
|
||||
nDataSize -= sizeof(T) * elems;
|
||||
AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadDataFromFile_Seek(size_t elems, AZ::IO::HandleType& fileHandle, int& nDataSize, [[maybe_unused]] EEndian eEndian);
|
||||
|
||||
template <class T>
|
||||
static bool LoadDataFromFile(T* data, size_t elems, uint8*& f, int& nDataSize, EEndian eEndian, [[maybe_unused]] int* pSeek = 0)
|
||||
{
|
||||
StepDataCopy(data, f, elems, eEndian);
|
||||
nDataSize -= elems * sizeof(T);
|
||||
AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0");
|
||||
return (nDataSize >= 0);
|
||||
}
|
||||
|
||||
bool LoadDataFromFile_Seek(size_t elems, uint8*& f, int& nDataSize, [[maybe_unused]] EEndian eEndian);
|
||||
|
||||
void LoadDataFromFile_FixAlignment(AZ::IO::HandleType& fileHandle, int& nDataSize);
|
||||
|
||||
void LoadDataFromFile_FixAlignment(uint8*& f, int& nDataSize);
|
||||
|
||||
} //namespace PakLoadDataUtils
|
||||
@@ -242,9 +242,6 @@ typedef uint32 vtx_idx;
|
||||
#endif // TESSELLATION
|
||||
#endif // !defined(MOBILE)
|
||||
|
||||
|
||||
#define USE_GEOM_CACHES
|
||||
|
||||
//------------------------------------------------------
|
||||
// SVO GI
|
||||
//------------------------------------------------------
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_QTANGENT_H
|
||||
#define CRYINCLUDE_CRYCOMMON_QTANGENT_H
|
||||
#pragma once
|
||||
|
||||
namespace QTangent {
|
||||
// Computes a QTangent from a frame and reflection scalar representing the
|
||||
// tangent space.
|
||||
// Will also ensure the resulting QTangent is suitable for 16bit quantization.
|
||||
ILINE Quat FromFrameReflection(Quat frame, const float reflection)
|
||||
{
|
||||
frame.v = -frame.v;
|
||||
if (frame.w < 0.0f)
|
||||
{
|
||||
frame = -frame;
|
||||
}
|
||||
|
||||
// Make sure w is never 0 by applying the smallest possible bias.
|
||||
// This is needed in order to have sign() never return 0 in the shaders.
|
||||
static const float BIAS_16BIT = 1.0f / 32767.0f;
|
||||
static const float BIAS_SCALE_16BIT = sqrtf(1.0f - BIAS_16BIT * BIAS_16BIT);
|
||||
if (frame.w < BIAS_16BIT && frame.w > -BIAS_16BIT)
|
||||
{
|
||||
frame *= BIAS_SCALE_16BIT;
|
||||
frame.w = BIAS_16BIT;
|
||||
}
|
||||
|
||||
if (reflection < 0.0f)
|
||||
{
|
||||
frame = -frame;
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
ILINE Quat FromFrameReflection(const Matrix33& frame, const float reflection)
|
||||
{
|
||||
Quat quat(frame);
|
||||
quat.Normalize();
|
||||
return FromFrameReflection(quat, reflection);
|
||||
}
|
||||
|
||||
ILINE Quat FromFrameReflection16Safe(Matrix33 frame, const float reflection)
|
||||
{
|
||||
frame.OrthonormalizeFast();
|
||||
if (!frame.IsOrthonormalRH(0.1f))
|
||||
{
|
||||
frame.SetIdentity();
|
||||
}
|
||||
|
||||
return FromFrameReflection(frame, reflection);
|
||||
}
|
||||
|
||||
ILINE void ToTangentBitangentReflection(const Quat& qtangent, Vec3& tangent, Vec3& bitangent, float& reflection)
|
||||
{
|
||||
tangent = qtangent.GetColumn0();
|
||||
bitangent = qtangent.GetColumn1();
|
||||
reflection = qtangent.w < 0.0f ? -1.0f : +1.0f;
|
||||
}
|
||||
} // namespace QTangent
|
||||
|
||||
// Auxiliary helper functions
|
||||
|
||||
#include <IIndexedMesh.h> // <> required for Interfuscator
|
||||
|
||||
ILINE Quat MeshTangentFrameToQTangent(const SMeshTangents& tangents)
|
||||
{
|
||||
SMeshTangents tb = tangents;
|
||||
Vec3 tangent32, bitangent32;
|
||||
int16 reflection;
|
||||
|
||||
tb.GetTB(tangent32, bitangent32);
|
||||
tb.GetR(reflection);
|
||||
|
||||
Matrix33 frame;
|
||||
|
||||
frame.SetRow(0, tangent32);
|
||||
frame.SetRow(1, bitangent32);
|
||||
frame.SetRow(2, tangent32.Cross(bitangent32).GetNormalized());
|
||||
|
||||
return QTangent::FromFrameReflection16Safe(frame, reflection);
|
||||
}
|
||||
|
||||
ILINE Quat MeshTangentFrameToQTangent(const Vec4sf& tangent, const Vec4sf& bitangent)
|
||||
{
|
||||
return MeshTangentFrameToQTangent(SMeshTangents(tangent, bitangent));
|
||||
}
|
||||
|
||||
ILINE Quat MeshTangentFrameToQTangent(const SPipTangents& tangents)
|
||||
{
|
||||
return MeshTangentFrameToQTangent(SMeshTangents(tangents));
|
||||
}
|
||||
|
||||
ILINE bool MeshTangentsFrameToQTangents(
|
||||
const Vec4sf* pTangent, const uint tangentStride,
|
||||
const Vec4sf* pBitangent, const uint bitangentStride, const uint count,
|
||||
SPipQTangents* pQTangents, const uint qtangentStride)
|
||||
{
|
||||
Quat qtangent;
|
||||
for (uint i = 0; i < count; ++i)
|
||||
{
|
||||
qtangent = MeshTangentFrameToQTangent(*pTangent, *pBitangent);
|
||||
SMeshQTangents(qtangent).ExportTo(*pQTangents);
|
||||
|
||||
pTangent = (const Vec4sf*)(((const uint8*)pTangent) + tangentStride);
|
||||
pBitangent = (const Vec4sf*)(((const uint8*)pBitangent) + bitangentStride);
|
||||
pQTangents = (SPipQTangents*)(((uint8*)pQTangents) + qtangentStride);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ILINE bool MeshTangentsFrameToQTangents(
|
||||
const SPipTangents* pTangents, const uint tangentStride, const uint count,
|
||||
SPipQTangents* pQTangents, const uint qtangentStride)
|
||||
{
|
||||
Quat qtangent;
|
||||
for (uint i = 0; i < count; ++i)
|
||||
{
|
||||
qtangent = MeshTangentFrameToQTangent(*pTangents);
|
||||
SMeshQTangents(qtangent).ExportTo(*pQTangents);
|
||||
|
||||
pTangents = (const SPipTangents*)(((const uint8*)pTangents) + tangentStride);
|
||||
pQTangents = (SPipQTangents*)(((uint8*)pQTangents) + qtangentStride);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ILINE bool MeshTangentsFrameToQTangents(
|
||||
const SMeshTangents* pTangents, const uint tangentStride, const uint count,
|
||||
SMeshQTangents* pQTangents, const uint qtangentStride)
|
||||
{
|
||||
Quat qtangent;
|
||||
for (uint i = 0; i < count; ++i)
|
||||
{
|
||||
qtangent = MeshTangentFrameToQTangent(*pTangents);
|
||||
*pQTangents = SMeshQTangents(qtangent);
|
||||
|
||||
pTangents = (const SMeshTangents*)(((const uint8*)pTangents) + tangentStride);
|
||||
pQTangents = (SMeshQTangents*)(((uint8*)pQTangents) + qtangentStride);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_QTANGENT_H
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class ReflectContext;
|
||||
}
|
||||
|
||||
namespace AzRTT
|
||||
{
|
||||
typedef AZ::Uuid RenderContextId;
|
||||
|
||||
// various post screen effects will fail if we attempt to render the scene to very
|
||||
// small render target sizes so provide a reasonable minimum (tile/icon size)
|
||||
constexpr uint32_t MinRenderTargetWidth = 32;
|
||||
constexpr uint32_t MinRenderTargetHeight = 32;
|
||||
|
||||
// this maximum recommended texture size applies to width and height
|
||||
// using sizes larger than this can lead to performance issues and instability
|
||||
constexpr uint32_t MaxRecommendedRenderTargetSize = 2048;
|
||||
|
||||
enum class AlphaMode {
|
||||
ALPHA_DISABLED = 0,
|
||||
ALPHA_OPAQUE,
|
||||
ALPHA_DEPTH_BASED
|
||||
};
|
||||
|
||||
// RenderContextConfig stores the render settings to use when rendering to texture.
|
||||
// It also provides a more developer-friendly interface to deal with by exposing
|
||||
// the most commonly used properties in one place.
|
||||
struct RenderContextConfig
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR(RenderContextConfig, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(RenderContextConfig, "{6114F930-CBE4-4373-AF9D-3B5319471C8F}");
|
||||
virtual ~RenderContextConfig() = default;
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
//! render target width
|
||||
uint32_t m_width = 256;
|
||||
|
||||
//! render target height
|
||||
uint32_t m_height = 256;
|
||||
|
||||
//! write srgb or linear output
|
||||
bool m_sRGBWrite = false;
|
||||
|
||||
//! alpha mode to use for the render target
|
||||
AlphaMode m_alphaMode = AlphaMode::ALPHA_OPAQUE;
|
||||
|
||||
//! scene settings
|
||||
bool m_oceanEnabled = true;
|
||||
bool m_terrainEnabled = true;
|
||||
bool m_vegetationEnabled = true;
|
||||
|
||||
//! shadow settings
|
||||
bool m_shadowsEnabled = true;
|
||||
int32_t m_shadowsNumCascades = -1;
|
||||
float m_shadowsGSMRange = -1.f;
|
||||
float m_shadowsGSMRangeStep = -1.f;
|
||||
|
||||
//! post-effects settings
|
||||
bool m_depthOfFieldEnabled = false;
|
||||
bool m_motionBlurEnabled = false;
|
||||
int m_aaMode = 0;
|
||||
|
||||
//! visiblity for shadow settings
|
||||
AZ::Crc32 GetShadowSettingsVisible();
|
||||
|
||||
//! confirm if user wants to use texture size larger than MaxRecommendedRenderTargetSize
|
||||
bool ValidateTextureSize(void* newValue, const AZ::Uuid& valueType);
|
||||
};
|
||||
}
|
||||
@@ -1,273 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright (C), Crytek, 1999-2015.
|
||||
#pragma once
|
||||
|
||||
// A fixed-size type-safe ring buffer (ie, fixed-size double-ended queue).
|
||||
// Note: It's possible to add support for iterators, indexing if needed.
|
||||
template<typename T, size_t N, typename I = uint32>
|
||||
class CRingBuffer
|
||||
{
|
||||
static_assert(std::is_integral<I>::value && std::is_unsigned<I>::value, "I is not unsigned integral type");
|
||||
static_assert(N != 0 && N <= I(-1), "N is not a valid value (or I is too small)");
|
||||
enum : I
|
||||
{
|
||||
kPowerOf2 = (N & (N - 1)) == 0,
|
||||
kMaxSize = static_cast<I>(N),
|
||||
};
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef I size_type;
|
||||
|
||||
// Constructs an empty ring buffer.
|
||||
CRingBuffer()
|
||||
: m_begin(0)
|
||||
, m_count(0)
|
||||
{}
|
||||
|
||||
// Destroy a ring buffer.
|
||||
~CRingBuffer()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
// Retrieve the size of the collection.
|
||||
size_type size() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
// Retrieve the maximum size of the collection.
|
||||
size_type max_size() const
|
||||
{
|
||||
return kMaxSize;
|
||||
}
|
||||
|
||||
// Test if the collection is empty.
|
||||
bool empty() const
|
||||
{
|
||||
return m_count == 0;
|
||||
}
|
||||
|
||||
// Test if the collection is full.
|
||||
bool full() const
|
||||
{
|
||||
return m_count == kMaxSize;
|
||||
}
|
||||
|
||||
// Get the front-most item of the collection.
|
||||
// If the collection is empty, the behavior is undefined.
|
||||
reference front()
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty");
|
||||
return *ptr(m_begin);
|
||||
}
|
||||
|
||||
// Get the front-most item of the collection.
|
||||
// If the collection is empty, the behavior is undefined.
|
||||
const_reference front() const
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty");
|
||||
return *ptr(m_begin);
|
||||
}
|
||||
|
||||
// Get the back-most item of the collection.
|
||||
// If the collection is empty, the behavior is undefined.
|
||||
reference back()
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty");
|
||||
return *ptr(wrap(m_begin + m_count - 1));
|
||||
}
|
||||
|
||||
// Get the back-most item of the collection.
|
||||
// If the collection is empty, the behavior is undefined.
|
||||
const_reference back() const
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty");
|
||||
return *ptr(wrap(m_begin + m_count - 1));
|
||||
}
|
||||
|
||||
// Adds an item to the front of the collection.
|
||||
// In case the collection is full, the function returns false and the collection remains unmodified.
|
||||
template<typename X>
|
||||
bool push_front(X&& value)
|
||||
{
|
||||
static_assert(std::is_constructible<T, X&&>::value, "T cannot be constructed from the given type");
|
||||
if (full())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const I index = decrement(m_begin);
|
||||
::new(static_cast<void*>(ptr(index)))T(std::forward<X>(value));
|
||||
m_begin = index;
|
||||
++m_count;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adds an item to the front of the collection.
|
||||
// In case the collection is full, the function overwrites the last item in the collection.
|
||||
template<typename X>
|
||||
void push_front_overwrite(X&& value)
|
||||
{
|
||||
static_assert(std::is_constructible<T, X&&>::value, "T cannot be constructed from the given type");
|
||||
const I index = decrement(m_begin);
|
||||
if (full())
|
||||
{
|
||||
ptr(index)->~T();
|
||||
--m_count;
|
||||
}
|
||||
::new(static_cast<void*>(ptr(index)))T(std::forward<X>(value));
|
||||
m_begin = index;
|
||||
++m_count;
|
||||
}
|
||||
|
||||
// Removes an item from the front of the collection.
|
||||
// If the collection is empty, the behavior is undefined.
|
||||
void pop_front()
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty");
|
||||
ptr(m_begin)->~T();
|
||||
m_begin = increment(m_begin);
|
||||
--m_count;
|
||||
}
|
||||
|
||||
// Attempts to remove an item from the front of the collection, and assigns it to 'value'.
|
||||
// Returns true if an item was removed, false if the collection was empty (and 'value' remains unmodified).
|
||||
bool try_pop_front(T& value)
|
||||
{
|
||||
if (m_count != 0)
|
||||
{
|
||||
T* const pItem = ptr(m_begin);
|
||||
value = std::move(*pItem);
|
||||
pItem->~T();
|
||||
m_begin = increment(m_begin);
|
||||
--m_count;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Adds an item to the back of the collection.
|
||||
// In case the collection is full, the function returns false and the collection remains unmodified.
|
||||
template<typename X>
|
||||
bool push_back(X&& value)
|
||||
{
|
||||
static_assert(std::is_constructible<T, X&&>::value, "T cannot be constructed from the given type");
|
||||
if (full())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const I index = wrap(m_begin + m_count);
|
||||
::new(static_cast<void*>(ptr(index)))T(std::forward<X>(value));
|
||||
++m_count;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adds an item to the back of the collection.
|
||||
// In case the collection is full, the function overwrites the first item in the collection.
|
||||
template<typename X>
|
||||
void push_back_overwrite(X&& value)
|
||||
{
|
||||
static_assert(std::is_constructible<T, X&&>::value, "T cannot be constructed from the given type");
|
||||
const I index = wrap(m_begin + m_count);
|
||||
if (full())
|
||||
{
|
||||
ptr(index)->~T();
|
||||
m_begin = increment(index);
|
||||
--m_count;
|
||||
}
|
||||
::new(static_cast<void*>(ptr(index)))T(std::forward<X>(value));
|
||||
++m_count;
|
||||
}
|
||||
|
||||
// Removes an item from the back of the collection.
|
||||
// If the collection is empty, the behavior is undefined.
|
||||
void pop_back()
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty");
|
||||
const I index = wrap(m_begin + m_count - 1);
|
||||
ptr(index)->~T();
|
||||
--m_count;
|
||||
}
|
||||
|
||||
// Attempts to remove an item from the back of the collection, and assigns it to 'value'.
|
||||
// Returns true if an item was removed, false if the collection was empty (and 'value' remains unmodified).
|
||||
bool try_pop_back(T& value)
|
||||
{
|
||||
if (m_count != 0)
|
||||
{
|
||||
const I index = wrap(m_begin + m_count - 1);
|
||||
T* const pItem = ptr(index);
|
||||
value = std::move(*pItem);
|
||||
pItem->~T();
|
||||
--m_count;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Destroy all items in a ring buffer.
|
||||
void clear()
|
||||
{
|
||||
size_type index = m_begin;
|
||||
for (size_type i = 0; i < m_count; ++i, index = increment(index))
|
||||
{
|
||||
ptr(index)->~T();
|
||||
}
|
||||
m_begin = 0;
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
// Decrements a given index, wrapping it around N.
|
||||
static size_type decrement(size_type index)
|
||||
{
|
||||
return kPowerOf2 ? ((index - 1) & (kMaxSize - 1)) : index ? index - 1 : kMaxSize - 1;
|
||||
}
|
||||
|
||||
// Increments a given index, wrapping it around N.
|
||||
static size_type increment(size_type index)
|
||||
{
|
||||
++index;
|
||||
return kPowerOf2 ? index & (kMaxSize - 1) : index == kMaxSize ? 0 : index;
|
||||
}
|
||||
|
||||
// Wraps an index, which has a maximum value of 2N-1.
|
||||
static size_type wrap(size_type index)
|
||||
{
|
||||
return kPowerOf2 ? index & (kMaxSize - 1) : index >= kMaxSize ? index - kMaxSize : index;
|
||||
}
|
||||
|
||||
// Obtain pointer to raw storage at given index.
|
||||
pointer ptr(size_type index)
|
||||
{
|
||||
return reinterpret_cast<pointer>(&m_storage) + index;
|
||||
}
|
||||
|
||||
// Obtain pointer to raw storage at given index.
|
||||
const_pointer ptr(size_type index) const
|
||||
{
|
||||
return reinterpret_cast<const_pointer>(&m_storage) + index;
|
||||
}
|
||||
|
||||
// No copy/assign supported.
|
||||
CRingBuffer(const CRingBuffer&);
|
||||
void operator=(const CRingBuffer&);
|
||||
|
||||
size_type m_begin, m_count;
|
||||
typename std::aligned_storage<sizeof(T)* N, std::alignment_of<T>::value>::type m_storage;
|
||||
};
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#undef AZ_RESTRICTED_SECTION
|
||||
#define SCOPEGUARD_H_SECTION_1 1
|
||||
#define SCOPEGUARD_H_SECTION_2 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
This is from the c++17 working draft paper N3949 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3949.pdf
|
||||
It is a new library addition targeted for c++17. I didn't feel like waiting. Only modification is as required to get the
|
||||
code compiling in the yet to be c++11 compliant visual studio. It is similar to boost scope exit, but in a modern and
|
||||
more feature rich form. scope_guard just executes a lambda when it goes out of scope. unique_resource is a more complete
|
||||
RAII wrapper. Its stands in for a resource (i.e. overloads cast operator to the wrapped resource) and frees it when it
|
||||
goes out of scope. see the paper for more examples and a better description. Get rid of this once c++17 is available.
|
||||
*/
|
||||
namespace std17
|
||||
{
|
||||
template <typename D>
|
||||
struct scope_guard_t
|
||||
{
|
||||
// construction
|
||||
explicit scope_guard_t(D&& f)
|
||||
: deleter(std::move(f))
|
||||
, execute_on_destruction(true)
|
||||
{
|
||||
}
|
||||
// move
|
||||
scope_guard_t(scope_guard_t&& rhs)
|
||||
: deleter(std::move(rhs.deleter))
|
||||
, execute_on_destruction(rhs.execute_on_destruction)
|
||||
{
|
||||
rhs.release();
|
||||
}
|
||||
// release
|
||||
~scope_guard_t()
|
||||
{
|
||||
if (execute_on_destruction)
|
||||
{
|
||||
deleter();
|
||||
}
|
||||
}
|
||||
void release() { execute_on_destruction = false; }
|
||||
private:
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION SCOPEGUARD_H_SECTION_1
|
||||
#include AZ_RESTRICTED_FILE(ScopeGuard_h)
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#else
|
||||
scope_guard_t(scope_guard_t const&) = delete;
|
||||
void operator=(scope_guard_t const&) = delete;
|
||||
scope_guard_t& operator=(scope_guard_t&&) = delete;
|
||||
#endif
|
||||
D deleter;
|
||||
bool execute_on_destruction;
|
||||
// exposition only
|
||||
};
|
||||
|
||||
template <typename D>
|
||||
scope_guard_t<D> scope_guard(D&& deleter)
|
||||
{
|
||||
return scope_guard_t<D>(std::move(deleter));
|
||||
// fails with curlies
|
||||
}
|
||||
|
||||
enum class invoke_it
|
||||
{
|
||||
once, again
|
||||
};
|
||||
template<typename R, typename D>
|
||||
class unique_resource_t
|
||||
{
|
||||
R resource;
|
||||
D deleter;
|
||||
bool execute_on_destruction;
|
||||
// exposition only
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION SCOPEGUARD_H_SECTION_2
|
||||
#include AZ_RESTRICTED_FILE(ScopeGuard_h)
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#else
|
||||
unique_resource_t& operator=(unique_resource_t const&) = delete;
|
||||
unique_resource_t(unique_resource_t const&) = delete;
|
||||
#endif
|
||||
// no copies!
|
||||
public:
|
||||
// construction
|
||||
explicit unique_resource_t(R&& _resource, D&& _deleter, bool _shouldrun = true)
|
||||
: resource(std::move(_resource))
|
||||
, deleter(std::move(_deleter))
|
||||
, execute_on_destruction(_shouldrun)
|
||||
{
|
||||
}
|
||||
// move
|
||||
unique_resource_t(unique_resource_t&& other)
|
||||
: resource(std::move(other.resource))
|
||||
, deleter(std::move(other.deleter))
|
||||
, execute_on_destruction(other.execute_on_destruction)
|
||||
{
|
||||
other.release();
|
||||
}
|
||||
unique_resource_t& operator=(unique_resource_t&& other)
|
||||
{
|
||||
this->invoke(invoke_it::once);
|
||||
deleter = std::move(other.deleter);
|
||||
resource = std::move(other.resource);
|
||||
execute_on_destruction = other.execute_on_destruction;
|
||||
other.release();
|
||||
return *this;
|
||||
}
|
||||
// resource release
|
||||
~unique_resource_t()
|
||||
{
|
||||
this->invoke(invoke_it::once);
|
||||
}
|
||||
void invoke(invoke_it const strategy = invoke_it::once)
|
||||
{
|
||||
if (execute_on_destruction)
|
||||
{
|
||||
get_deleter()(resource);
|
||||
}
|
||||
execute_on_destruction = strategy == invoke_it::again;
|
||||
}
|
||||
R const& release()
|
||||
{
|
||||
execute_on_destruction = false;
|
||||
return this->get();
|
||||
}
|
||||
void reset(R&& newresource)
|
||||
{
|
||||
invoke(invoke_it::again);
|
||||
resource = std::move(newresource);
|
||||
}
|
||||
// resource access
|
||||
R const& get() const
|
||||
{
|
||||
return resource;
|
||||
}
|
||||
operator R const& () const
|
||||
{
|
||||
return resource;
|
||||
}
|
||||
R operator->() const
|
||||
{
|
||||
return resource;
|
||||
}
|
||||
typename std::add_lvalue_reference<typename std::remove_pointer<R>::type>::type operator*() const
|
||||
{
|
||||
return *resource;
|
||||
}
|
||||
// deleter access
|
||||
const D& get_deleter() const
|
||||
{
|
||||
return deleter;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename R, typename D>
|
||||
unique_resource_t<R, D> unique_resource(R&& r, D t)
|
||||
{
|
||||
return unique_resource_t<R, D>(std::move(r), std::move(t), true);
|
||||
}
|
||||
|
||||
template<typename R, typename D>
|
||||
unique_resource_t<R, D> unique_resource_checked(R r, R invalid, D t)
|
||||
{
|
||||
bool shouldrun = (r != invalid);
|
||||
return unique_resource_t<R, D>(std::move(r), std::move(t), shouldrun);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// This header is provided for backwards compatibility. Avoid including this header, instead
|
||||
// include the needed smart ptr headers
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/std/smart_ptr/weak_ptr.h>
|
||||
|
||||
#define DECLARE_SMART_POINTERS(name) \
|
||||
typedef AZStd::shared_ptr<name> name##Ptr; \
|
||||
typedef AZStd::shared_ptr<const name> name##ConstPtr; \
|
||||
typedef AZStd::weak_ptr<name> name##WeakPtr; \
|
||||
typedef AZStd::weak_ptr<const name> name##ConstWeakPtr;
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Helper to enable inplace construction and destruction of objects
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_STACKCONTAINER_H
|
||||
#define CRYINCLUDE_CRYCOMMON_STACKCONTAINER_H
|
||||
#pragma once
|
||||
|
||||
#include <InplaceFactory.h>
|
||||
|
||||
// Class that contains a non-pod data type allocated on the stack via placement
|
||||
// new. Constructor parameters up to an arity of 5 are forwarded over an
|
||||
// inplace factory expression.
|
||||
template<typename T>
|
||||
class CStackContainer
|
||||
{
|
||||
// The backing storage
|
||||
uint8 m_Storage[ sizeof (T) ];
|
||||
|
||||
// Constructs the object via an inplace factory
|
||||
template<class Factory>
|
||||
void construct (const Factory& factory)
|
||||
{
|
||||
factory.template apply<T>(m_Storage);
|
||||
}
|
||||
|
||||
// Destructs the object. The destructor of the contained object is called
|
||||
void destruct ()
|
||||
{
|
||||
reinterpret_cast<T*>(m_Storage)->~T();
|
||||
}
|
||||
|
||||
// Prevent the object to be placed on the heap
|
||||
// (.... it simply wouldn't make much sense)
|
||||
void* operator new(size_t);
|
||||
void operator delete(void*);
|
||||
|
||||
public:
|
||||
|
||||
// Constructs inside the object
|
||||
template<class Expr>
|
||||
CStackContainer (const Expr& expr)
|
||||
{ construct(expr); }
|
||||
|
||||
// Destructs the object contained
|
||||
~CStackContainer() { destruct(); }
|
||||
|
||||
// Accessor methods
|
||||
T* get() { return reinterpret_cast<T*>(m_Storage); }
|
||||
const T* get() const { return reinterpret_cast<const T*>(m_Storage); }
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_STACKCONTAINER_H
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <CrySizer.h>
|
||||
#include <CryPodArray.h>
|
||||
|
||||
template <class T>
|
||||
class TPool
|
||||
{
|
||||
public:
|
||||
|
||||
TPool(int nPoolSize)
|
||||
{
|
||||
m_nPoolSize = nPoolSize;
|
||||
m_pPool = new T[nPoolSize];
|
||||
m_lstFree.PreAllocate(nPoolSize, 0);
|
||||
m_lstUsed.PreAllocate(nPoolSize, 0);
|
||||
for (int i = 0; i < nPoolSize; i++)
|
||||
{
|
||||
m_lstFree.Add(&m_pPool[i]);
|
||||
}
|
||||
}
|
||||
|
||||
~TPool()
|
||||
{
|
||||
delete[] m_pPool;
|
||||
}
|
||||
|
||||
void ReleaseObject(T* pInst)
|
||||
{
|
||||
if (m_lstUsed.Delete(pInst))
|
||||
{
|
||||
m_lstFree.Add(pInst);
|
||||
}
|
||||
}
|
||||
|
||||
int GetUsedInstancesCount(int& nAll)
|
||||
{
|
||||
nAll = m_nPoolSize;
|
||||
return m_lstUsed.Count();
|
||||
}
|
||||
|
||||
T* GetObject()
|
||||
{
|
||||
T* pInst = NULL;
|
||||
if (m_lstFree.Count())
|
||||
{
|
||||
pInst = m_lstFree.Last();
|
||||
m_lstFree.DeleteLast();
|
||||
m_lstUsed.Add(pInst);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!"TPool::GetObject: Out of free elements error");
|
||||
}
|
||||
|
||||
return pInst;
|
||||
}
|
||||
|
||||
void GetMemoryUsage(class ICrySizer* pSizer) const
|
||||
{
|
||||
pSizer->AddObject(m_lstFree);
|
||||
pSizer->AddObject(m_lstUsed);
|
||||
|
||||
if (m_pPool)
|
||||
{
|
||||
for (int i = 0; i < m_nPoolSize; i++)
|
||||
{
|
||||
m_pPool[i].GetMemoryUsage(pSizer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PodArray<T*> m_lstFree;
|
||||
PodArray<T*> m_lstUsed;
|
||||
T* m_pPool;
|
||||
int m_nPoolSize;
|
||||
};
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Generic unaligned memory access helpers.
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Detail
|
||||
{
|
||||
template<typename RealType, typename BlittedElement>
|
||||
struct Blitter
|
||||
{
|
||||
static_assert(std::is_trivial<BlittedElement>::value, "Blittable elements should be trivial (ie, integral types)");
|
||||
static_assert((std::alignment_of<BlittedElement>::value < std::alignment_of<RealType>::value), "Blittable memory has sufficient alignment, do not use unaligned store or load");
|
||||
static_assert(sizeof(RealType) > sizeof(BlittedElement), "Blittable element is larger than real type");
|
||||
static_assert((sizeof(RealType) % sizeof(BlittedElement)) == 0, "Blitted element has the wrong size for the real type");
|
||||
typedef std::integral_constant<size_t, sizeof(RealType) / sizeof(BlittedElement)> NumElements;
|
||||
|
||||
static void BlitLoad(const BlittedElement* pSource, RealType& target)
|
||||
{
|
||||
BlittedElement* pTarget = alias_cast<BlittedElement*>(&target);
|
||||
for (size_t i = 0; i < NumElements::value; ++i, ++pSource, ++pTarget)
|
||||
{
|
||||
* pTarget = *pSource;
|
||||
}
|
||||
}
|
||||
|
||||
static void BlitStore(const RealType& source, BlittedElement* pTarget)
|
||||
{
|
||||
const BlittedElement* pSource = alias_cast<const BlittedElement*>(&source);
|
||||
for (size_t i = 0; i < NumElements::value; ++i, ++pSource, ++pTarget)
|
||||
{
|
||||
* pTarget = *pSource;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Load RealType from unaligned memory using some blittable type.
|
||||
// The source memory must be suitably aligned for accessing BlittedElement.
|
||||
// If no memory alignment can be guaranteed, use char for BlittedElement.
|
||||
template<typename RealType, typename BlittedElement>
|
||||
inline void LoadUnaligned(const BlittedElement* pMemory, RealType& value,
|
||||
typename std::enable_if<(std::alignment_of<RealType>::value > std::alignment_of<BlittedElement>::value)>::type* = nullptr)
|
||||
{
|
||||
Detail::Blitter<RealType, BlittedElement>::BlitLoad(pMemory, value);
|
||||
}
|
||||
|
||||
// Load RealType from aligned memory (fallback overload).
|
||||
// This is used if there is no reason to call the blitter, because sufficient alignment is guaranteed by BlittedElement.
|
||||
template<typename RealType, typename BlittedElement>
|
||||
inline void LoadUnaligned(const BlittedElement* pMemory, RealType& value,
|
||||
typename std::enable_if<(std::alignment_of<RealType>::value <= std::alignment_of<BlittedElement>::value)>::type* = nullptr)
|
||||
{
|
||||
value = *alias_cast<RealType*>(pMemory);
|
||||
}
|
||||
|
||||
// Store to unaligned memory using some blittable type.
|
||||
// The target memory must be suitably aligned for accessing BlittedElement.
|
||||
// If no memory alignment can be guaranteed, use char for BlittedElement.
|
||||
template<typename RealType, typename BlittedElement>
|
||||
inline void StoreUnaligned(BlittedElement* pMemory, const RealType& value,
|
||||
typename std::enable_if<(std::alignment_of<RealType>::value > std::alignment_of<BlittedElement>::value)>::type* = nullptr)
|
||||
{
|
||||
Detail::Blitter<RealType, BlittedElement>::BlitStore(value, pMemory);
|
||||
}
|
||||
|
||||
// Store to aligned memory (fallback overload).
|
||||
// This is used if there is no reason to call the blitter, because sufficient alignment is guaranteed by BlittedElement.
|
||||
template<typename RealType, typename BlittedElement>
|
||||
inline void StoreUnaligned(BlittedElement* pMemory, const RealType& value,
|
||||
typename std::enable_if<(std::alignment_of<RealType>::value <= std::alignment_of<BlittedElement>::value)>::type* = nullptr)
|
||||
{
|
||||
*alias_cast<RealType*>(pMemory) = value;
|
||||
}
|
||||
|
||||
// Pads the given pointer to the next possible aligned location for RealType
|
||||
// Use this to ensure RealType can be referenced in some buffer of BlittedElement's, without using LoadUnaligned/StoreUnaligned
|
||||
template<typename RealType, typename BlittedElement>
|
||||
inline BlittedElement* AlignPointer(BlittedElement* pMemory,
|
||||
typename std::enable_if<(std::alignment_of<RealType>::value % std::alignment_of<BlittedElement>::value) == 0>::type* = nullptr)
|
||||
{
|
||||
const size_t align = std::alignment_of<RealType>::value;
|
||||
const size_t mask = align - 1;
|
||||
const size_t address = reinterpret_cast<size_t>(pMemory);
|
||||
const size_t offset = (align - (address & mask)) & mask;
|
||||
return pMemory + (offset / sizeof(BlittedElement));
|
||||
}
|
||||
|
||||
// Pads the given address to the next possible aligned location for RealType
|
||||
// Use this to ensure RealType can be referenced inside memory, without using LoadUnaligned/StoreUnaligned
|
||||
template<typename RealType>
|
||||
inline size_t AlignAddress(size_t address)
|
||||
{
|
||||
return reinterpret_cast<size_t>(AlignPointer<RealType>(reinterpret_cast<char*>(address)));
|
||||
}
|
||||
|
||||
// Provides aligned storage for T, optionally aligned at a specific boundary (default being the native alignment of T)
|
||||
// The specified T is not initialized automatically, use of placement new/delete is the user's responsibility
|
||||
template<typename T, size_t Align = std::alignment_of<T>::value>
|
||||
struct SUninitialized
|
||||
{
|
||||
typedef typename std::aligned_storage<sizeof(T), Align>::type Storage;
|
||||
Storage storage;
|
||||
|
||||
void DefaultConstruct()
|
||||
{
|
||||
new(static_cast<void*>(&storage))T();
|
||||
}
|
||||
|
||||
void CopyConstruct(const T& value)
|
||||
{
|
||||
new(static_cast<void*>(&storage))T(value);
|
||||
}
|
||||
|
||||
void MoveConstruct(T&& value)
|
||||
{
|
||||
new(static_cast<void*>(&storage))T(std::move(value));
|
||||
}
|
||||
|
||||
void Destruct()
|
||||
{
|
||||
alias_cast<T*>(&storage)->~T();
|
||||
}
|
||||
|
||||
operator T& ()
|
||||
{
|
||||
return *alias_cast<T*>(&storage);
|
||||
}
|
||||
};
|
||||
@@ -10,23 +10,16 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
QTangent.h
|
||||
CryCommon.cpp
|
||||
FinalizingSpline.h
|
||||
IAudioInterfacesCommonData.h
|
||||
IAudioSystem.h
|
||||
IChunkFile.h
|
||||
ICmdLine.h
|
||||
IColorGradingController.h
|
||||
IConsole.h
|
||||
IEntityRenderState.h
|
||||
IEntityRenderState_info.cpp
|
||||
IFont.h
|
||||
IFunctorBase.h
|
||||
IFuncVariable.h
|
||||
IGem.h
|
||||
IGeomCache.h
|
||||
IImage.h
|
||||
IIndexedMesh.h
|
||||
IIndexedMesh_info.cpp
|
||||
ILevelSystem.h
|
||||
@@ -35,11 +28,9 @@ set(FILES
|
||||
LocalizationManagerBus.inl
|
||||
ILog.h
|
||||
IMaterial.h
|
||||
IMeshBaking.h
|
||||
IMiniLog.h
|
||||
IMovieSystem.h
|
||||
IPhysics.h
|
||||
IPhysicsDebugRenderer.h
|
||||
IPostEffectGroup.h
|
||||
IProcess.h
|
||||
IReadWriteXMLSink.h
|
||||
@@ -48,7 +39,6 @@ set(FILES
|
||||
IRenderMesh.h
|
||||
ISerialize.h
|
||||
IShader.h
|
||||
IShader_info.h
|
||||
ISplines.h
|
||||
IStatObj.h
|
||||
StatObjBus.h
|
||||
@@ -58,18 +48,15 @@ set(FILES
|
||||
ITexture.h
|
||||
ITimer.h
|
||||
IValidator.h
|
||||
IVideoRenderer.h
|
||||
IViewSystem.h
|
||||
IWindowMessageHandler.h
|
||||
IXml.h
|
||||
IProximityTriggerSystem.h
|
||||
MicrophoneBus.h
|
||||
physinterface.h
|
||||
HMDBus.h
|
||||
VRCommon.h
|
||||
StereoRendererBus.h
|
||||
HeightmapUpdateNotificationBus.h
|
||||
IObjManager.h
|
||||
INavigationSystem.h
|
||||
IMNM.h
|
||||
SFunctor.h
|
||||
@@ -82,18 +69,15 @@ set(FILES
|
||||
CryRandomInternal.h
|
||||
Random.h
|
||||
LCGRandom.h
|
||||
MaterialUtils.h
|
||||
MTPseudoRandom.cpp
|
||||
CryTypeInfo.cpp
|
||||
BaseTypes.h
|
||||
CompileTimeAssert.h
|
||||
intrusive_list.hpp
|
||||
MemoryAccess.h
|
||||
AnimKey.h
|
||||
BitFiddling.h
|
||||
Common_TypeInfo.cpp
|
||||
CryArray.h
|
||||
CryArray2d.h
|
||||
CryAssert.h
|
||||
CryCrc32.h
|
||||
CryCustomTypes.h
|
||||
@@ -106,44 +90,31 @@ set(FILES
|
||||
CryName.h
|
||||
CryPath.h
|
||||
CryPodArray.h
|
||||
CryPtrArray.h
|
||||
CrySizer.h
|
||||
CryString.h
|
||||
CrySystemBus.h
|
||||
CryThread.h
|
||||
CryThreadImpl.h
|
||||
CryTypeInfo.h
|
||||
CryUtils.h
|
||||
CryVersion.h
|
||||
CryZlib.h
|
||||
FrameProfiler.h
|
||||
HashGrid.h
|
||||
HeapAllocator.h
|
||||
HeapContainer.h
|
||||
InplaceFactory.h
|
||||
LegacyAllocator.h
|
||||
MetaUtils.h
|
||||
MiniQueue.h
|
||||
MTPseudoRandom.h
|
||||
MultiThread.h
|
||||
MultiThread_Containers.h
|
||||
Name_TypeInfo.h
|
||||
NullAudioSystem.h
|
||||
PNoise3.h
|
||||
PoolAllocator.h
|
||||
primitives.h
|
||||
primitives_info.h
|
||||
ProjectDefines.h
|
||||
Range.h
|
||||
RenderContextConfig.h
|
||||
RingBuffer.h
|
||||
ScopeGuard.h
|
||||
ScopedVariableSetter.h
|
||||
SerializeFwd.h
|
||||
SimpleSerialize.h
|
||||
SmartPointersHelpers.h
|
||||
smartptr.h
|
||||
StackContainer.h
|
||||
StlUtils.h
|
||||
StringUtils.h
|
||||
Synchronization.h
|
||||
@@ -153,7 +124,6 @@ set(FILES
|
||||
TimeValue_info.h
|
||||
TypeInfo_decl.h
|
||||
TypeInfo_impl.h
|
||||
UnalignedBlit.h
|
||||
UnicodeBinding.h
|
||||
UnicodeEncoding.h
|
||||
UnicodeFunctions.h
|
||||
@@ -164,10 +134,6 @@ set(FILES
|
||||
XMLBinaryHeaders.h
|
||||
RenderBus.h
|
||||
MainThreadRenderRequestBus.h
|
||||
OceanConstants.h
|
||||
PakLoadDataUtils.cpp
|
||||
PakLoadDataUtils.h
|
||||
TPool.h
|
||||
Cry_Matrix33.h
|
||||
Cry_Matrix34.h
|
||||
Cry_Matrix44.h
|
||||
@@ -186,7 +152,6 @@ set(FILES
|
||||
Cry_Vector3.h
|
||||
Cry_XOptimise.h
|
||||
CryHalf_info.h
|
||||
GeomQuery.h
|
||||
CryHalf.inl
|
||||
MathConversion.h
|
||||
Cry_HWMatrix.h
|
||||
@@ -308,6 +273,5 @@ set(FILES
|
||||
Maestro/Types/AssetBlends.h
|
||||
Maestro/Types/SequenceType.h
|
||||
StaticInstance.h
|
||||
Pak/CryPakUtils.h
|
||||
WinBase.cpp
|
||||
)
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef _INTRUSIVE_LIST_HPP
|
||||
#define _INTRUSIVE_LIST_HPP
|
||||
#if !defined(WIN32)
|
||||
#include <stdint.h>
|
||||
#endif //!defined(WIN32)
|
||||
|
||||
|
||||
namespace util
|
||||
{
|
||||
// Simple lightweight intrusive list utility
|
||||
//
|
||||
template<typename Host>
|
||||
struct list
|
||||
{
|
||||
typedef Host value_type;
|
||||
|
||||
list* next;
|
||||
list* prev;
|
||||
|
||||
// Default (initializing) constructor
|
||||
list()
|
||||
{
|
||||
next = this;
|
||||
prev = this;
|
||||
}
|
||||
|
||||
// Inserts this list into a given list item between
|
||||
// prev and next (note: they need to be sequential!)
|
||||
void insert(list* _prev, list* _next)
|
||||
{
|
||||
_next->prev = this;
|
||||
this->next = _next;
|
||||
this->prev = _prev;
|
||||
_prev->next = this;
|
||||
}
|
||||
|
||||
// Should only be called on heads
|
||||
void clear() { next = prev = this; }
|
||||
|
||||
// Removes from a list, then inserts this list item into a given list between
|
||||
// prev and next (note: they need to be sequential!)
|
||||
void re_insert(list* _prev, list* _next)
|
||||
{
|
||||
erase();
|
||||
insert(_prev, _next);
|
||||
}
|
||||
|
||||
|
||||
// Remove this list instance from a list
|
||||
// Safe to be called even if not attached to a list
|
||||
void erase()
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
next = prev = this;
|
||||
}
|
||||
|
||||
// Predicate to determine if a list structure is linked to a list
|
||||
bool empty() const { return prev == this && next == this; }
|
||||
bool linked() const { return !empty(); }
|
||||
|
||||
// Get the host instance of the instrusive list
|
||||
template<list Host::* member>
|
||||
Host* item()
|
||||
{
|
||||
return ((Host*)((uintptr_t)(this) - (uintptr_t)(&(((Host*)0)->*member))));
|
||||
}
|
||||
template<list Host::* member>
|
||||
const Host* item() const
|
||||
{
|
||||
return ((Host*)((uintptr_t)(this) - (uintptr_t)(&(((Host*)0)->*member))));
|
||||
}
|
||||
template<list (Host::* Member)[2]>
|
||||
Host * item(int threadId)
|
||||
{
|
||||
uintptr_t value = (uintptr_t)this - (uintptr_t)&((((Host*)(NULL))->*Member)[threadId]);
|
||||
return alias_cast<Host*>(value);
|
||||
}
|
||||
|
||||
// Insert & relink functions
|
||||
void insert_tail(list* _list) { insert(_list->prev, _list); }
|
||||
void insert_tail(list& _list) { insert_tail(&_list); }
|
||||
void insert_head(list* _list) { insert(_list, _list->next); }
|
||||
void insert_head(list& _list) { insert_head(&_list); }
|
||||
void relink_tail(list* _list) { erase(); insert_tail(_list); }
|
||||
void relink_tail(list& _list) { relink_tail(&_list); }
|
||||
void relink_head(list* _list) { erase(); insert_head(_list); }
|
||||
void relink_head(list& _list) { relink_head(&_list); }
|
||||
|
||||
static inline void splice(const list* _list, list* prev, list* next)
|
||||
{
|
||||
list* first = _list->next;
|
||||
list* last = _list->prev;
|
||||
|
||||
first->prev = prev;
|
||||
prev->next = first;
|
||||
|
||||
last->next = next;
|
||||
next->prev = last;
|
||||
}
|
||||
|
||||
void splice_front(const list* _list)
|
||||
{
|
||||
if (!_list->empty())
|
||||
{
|
||||
splice(_list, this, this->next);
|
||||
_list->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void splice_tail(list* _list)
|
||||
{
|
||||
if (!_list->empty())
|
||||
{
|
||||
splice(_list, this->prev, this);
|
||||
_list->clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Accessors
|
||||
list<Host>* tail() { return prev; }
|
||||
const list<Host>* tail() const { return prev; }
|
||||
list<Host>* head() { return head; }
|
||||
const list<Host>* head() const { return head; }
|
||||
};
|
||||
|
||||
// utility to extract the host type of an intrusive list at compile time
|
||||
template<typename List>
|
||||
struct list_value_type
|
||||
{
|
||||
typedef typename List::value_type value_type;
|
||||
};
|
||||
|
||||
// Loops over the list in forward manner, pos will be of type list<T>*
|
||||
# define list_for_each(pos, head) \
|
||||
for (typeof(head)pos = (head)->next; pos != (head); \
|
||||
pos = pos->next)
|
||||
|
||||
// Loops over the list in backward manner, pos will be of type list<T>*
|
||||
# define list_for_each_backwards(pos, head) \
|
||||
for (typeof(head)pos = (head)->prev; pos != (head); \
|
||||
pos = pos->prev)
|
||||
|
||||
// Loops over the list in forward manner while safeguarding
|
||||
// against list removal during iteration. pos will be of type list<T>*
|
||||
# define list_for_each_safe(pos, head) \
|
||||
for (typeof(head)pos = (head)->next, n = pos->next; pos != (head); \
|
||||
pos = n, n = pos->next)
|
||||
|
||||
// Loops over the list in forward manner. pos will be of type list<T>*
|
||||
# define list_for_each_entry(pos, head, member) \
|
||||
for (util::list_value_type<typeof((head))>::value_type* pos = \
|
||||
(head)->next->item<member>(); \
|
||||
&(pos->*(member)) != &list; \
|
||||
pos = ((pos->*(member)).next->item<member>()))
|
||||
|
||||
// Loops over the list in forward manner while safeguarding against list
|
||||
// removal during iteratation. pos will be of type T*
|
||||
# define list_for_each_entry_safe(pos, head, member) \
|
||||
for (util::list_value_type<typeof((head))>::value_type* pos = \
|
||||
(head)->next->item<member>(), \
|
||||
* n = ((pos->*(member)).next->item<member>()); \
|
||||
&(pos->*(member)) != &list; \
|
||||
pos = n, n = ((n->*(member)).next->item<member>()))
|
||||
} // end namespace util
|
||||
#endif // ifndef _INTRUSIVE_LIST_HPP
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_PRIMITIVES_INFO_H
|
||||
#define CRYINCLUDE_CRYCOMMON_PRIMITIVES_INFO_H
|
||||
#pragma once
|
||||
|
||||
#include "primitives.h"
|
||||
|
||||
STRUCT_INFO_TYPE_EMPTY(primitives::primitive)
|
||||
|
||||
STRUCT_INFO_BEGIN(primitives::box)
|
||||
STRUCT_BASE_INFO(primitives::primitive)
|
||||
STRUCT_VAR_INFO(Basis, TYPE_INFO(Matrix33))
|
||||
STRUCT_VAR_INFO(bOriented, TYPE_INFO(int))
|
||||
STRUCT_VAR_INFO(center, TYPE_INFO(Vec3))
|
||||
STRUCT_VAR_INFO(size, TYPE_INFO(Vec3))
|
||||
STRUCT_INFO_END(primitives::box)
|
||||
|
||||
STRUCT_INFO_BEGIN(primitives::sphere)
|
||||
STRUCT_BASE_INFO(primitives::primitive)
|
||||
STRUCT_VAR_INFO(center, TYPE_INFO(Vec3))
|
||||
STRUCT_VAR_INFO(r, TYPE_INFO(float))
|
||||
STRUCT_INFO_END(primitives::sphere)
|
||||
|
||||
STRUCT_INFO_BEGIN(primitives::cylinder)
|
||||
STRUCT_BASE_INFO(primitives::primitive)
|
||||
STRUCT_VAR_INFO(center, TYPE_INFO(Vec3))
|
||||
STRUCT_VAR_INFO(axis, TYPE_INFO(Vec3))
|
||||
STRUCT_VAR_INFO(r, TYPE_INFO(float))
|
||||
STRUCT_VAR_INFO(hh, TYPE_INFO(float))
|
||||
STRUCT_INFO_END(primitives::cylinder)
|
||||
|
||||
STRUCT_INFO_BEGIN(primitives::plane)
|
||||
STRUCT_BASE_INFO(primitives::primitive)
|
||||
STRUCT_VAR_INFO(n, TYPE_INFO(Vec3))
|
||||
STRUCT_VAR_INFO(origin, TYPE_INFO(Vec3))
|
||||
STRUCT_INFO_END(primitives::plane)
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_PRIMITIVES_INFO_H
|
||||
@@ -0,0 +1,900 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "CrySystem_precompiled.h"
|
||||
#include "DebugCallStack.h"
|
||||
|
||||
#if defined(WIN32) || defined(WIN64)
|
||||
|
||||
#include <IConsole.h>
|
||||
#include <CryPath.h>
|
||||
#include "System.h"
|
||||
|
||||
#include <AzCore/Debug/StackTracer.h>
|
||||
#include <AzCore/Debug/EventTraceDrillerBus.h>
|
||||
|
||||
#define VS_VERSION_INFO 1
|
||||
#define IDD_CRITICAL_ERROR 101
|
||||
#define IDB_CONFIRM_SAVE 102
|
||||
#define IDB_DONT_SAVE 103
|
||||
#define IDD_CONFIRM_SAVE_LEVEL 127
|
||||
#define IDB_CRASH_FACE 128
|
||||
#define IDD_EXCEPTION 245
|
||||
#define IDC_CALLSTACK 1001
|
||||
#define IDC_EXCEPTION_CODE 1002
|
||||
#define IDC_EXCEPTION_ADDRESS 1003
|
||||
#define IDC_EXCEPTION_MODULE 1004
|
||||
#define IDC_EXCEPTION_DESC 1005
|
||||
#define IDB_EXIT 1008
|
||||
#define IDB_IGNORE 1010
|
||||
__pragma(comment(lib, "version.lib"))
|
||||
|
||||
//! Needs one external of DLL handle.
|
||||
extern HMODULE gDLLHandle;
|
||||
|
||||
#include <DbgHelp.h>
|
||||
|
||||
#define MAX_PATH_LENGTH 1024
|
||||
#define MAX_SYMBOL_LENGTH 512
|
||||
|
||||
static HWND hwndException = 0;
|
||||
static bool g_bUserDialog = true; // true=on crash show dialog box, false=supress user interaction
|
||||
|
||||
static int PrintException(EXCEPTION_POINTERS* pex);
|
||||
|
||||
static bool IsFloatingPointException(EXCEPTION_POINTERS* pex);
|
||||
|
||||
extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers);
|
||||
extern LONG WINAPI CryEngineExceptionFilterMiniDump(struct _EXCEPTION_POINTERS* pExceptionPointers, const char* szDumpPath, MINIDUMP_TYPE mdumpValue);
|
||||
|
||||
//=============================================================================
|
||||
CONTEXT CaptureCurrentContext()
|
||||
{
|
||||
CONTEXT context;
|
||||
memset(&context, 0, sizeof(context));
|
||||
context.ContextFlags = CONTEXT_FULL;
|
||||
RtlCaptureContext(&context);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
LONG __stdcall CryUnhandledExceptionHandler(EXCEPTION_POINTERS* pex)
|
||||
{
|
||||
return DebugCallStack::instance()->handleException(pex);
|
||||
}
|
||||
|
||||
|
||||
BOOL CALLBACK EnumModules(
|
||||
PCSTR ModuleName,
|
||||
DWORD64 BaseOfDll,
|
||||
PVOID UserContext)
|
||||
{
|
||||
DebugCallStack::TModules& modules = *static_cast<DebugCallStack::TModules*>(UserContext);
|
||||
modules[(void*)BaseOfDll] = ModuleName;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
//=============================================================================
|
||||
// Class Statics
|
||||
//=============================================================================
|
||||
|
||||
// Return single instance of class.
|
||||
IDebugCallStack* IDebugCallStack::instance()
|
||||
{
|
||||
static DebugCallStack sInstance;
|
||||
return &sInstance;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
// Sets up the symbols for functions in the debug file.
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
DebugCallStack::DebugCallStack()
|
||||
: prevExceptionHandler(0)
|
||||
, m_pSystem(0)
|
||||
, m_nSkipNumFunctions(0)
|
||||
, m_bCrash(false)
|
||||
, m_szBugMessage(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
DebugCallStack::~DebugCallStack()
|
||||
{
|
||||
}
|
||||
|
||||
void DebugCallStack::RemoveOldFiles()
|
||||
{
|
||||
RemoveFile("error.log");
|
||||
RemoveFile("error.bmp");
|
||||
RemoveFile("error.dmp");
|
||||
}
|
||||
|
||||
void DebugCallStack::RemoveFile(const char* szFileName)
|
||||
{
|
||||
FILE* pFile = nullptr;
|
||||
azfopen(&pFile, szFileName, "r");
|
||||
const bool bFileExists = (pFile != NULL);
|
||||
|
||||
if (bFileExists)
|
||||
{
|
||||
fclose(pFile);
|
||||
|
||||
WriteLineToLog("Removing file \"%s\"...", szFileName);
|
||||
if (remove(szFileName) == 0)
|
||||
{
|
||||
WriteLineToLog("File successfully removed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLineToLog("Couldn't remove file!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DebugCallStack::installErrorHandler(ISystem* pSystem)
|
||||
{
|
||||
m_pSystem = pSystem;
|
||||
prevExceptionHandler = (void*)SetUnhandledExceptionFilter(CryUnhandledExceptionHandler);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DebugCallStack::SetUserDialogEnable(const bool bUserDialogEnable)
|
||||
{
|
||||
g_bUserDialog = bUserDialogEnable;
|
||||
}
|
||||
|
||||
|
||||
DWORD g_idDebugThreads[10];
|
||||
const char* g_nameDebugThreads[10];
|
||||
int g_nDebugThreads = 0;
|
||||
volatile int g_lockThreadDumpList = 0;
|
||||
|
||||
void MarkThisThreadForDebugging(const char* name)
|
||||
{
|
||||
EBUS_EVENT(AZ::Debug::EventTraceDrillerSetupBus, SetThreadName, AZStd::this_thread::get_id(), name);
|
||||
|
||||
WriteLock lock(g_lockThreadDumpList);
|
||||
DWORD id = GetCurrentThreadId();
|
||||
if (g_nDebugThreads == sizeof(g_idDebugThreads) / sizeof(g_idDebugThreads[0]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < g_nDebugThreads; i++)
|
||||
{
|
||||
if (g_idDebugThreads[i] == id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
g_nameDebugThreads[g_nDebugThreads] = name;
|
||||
g_idDebugThreads[g_nDebugThreads++] = id;
|
||||
((CSystem*)gEnv->pSystem)->EnableFloatExceptions(g_cvars.sys_float_exceptions);
|
||||
}
|
||||
|
||||
void UnmarkThisThreadFromDebugging()
|
||||
{
|
||||
WriteLock lock(g_lockThreadDumpList);
|
||||
DWORD id = GetCurrentThreadId();
|
||||
for (int i = g_nDebugThreads - 1; i >= 0; i--)
|
||||
{
|
||||
if (g_idDebugThreads[i] == id)
|
||||
{
|
||||
memmove(g_idDebugThreads + i, g_idDebugThreads + i + 1, (g_nDebugThreads - 1 - i) * sizeof(g_idDebugThreads[0]));
|
||||
memmove(g_nameDebugThreads + i, g_nameDebugThreads + i + 1, (g_nDebugThreads - 1 - i) * sizeof(g_nameDebugThreads[0]));
|
||||
--g_nDebugThreads;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern int prev_sys_float_exceptions;
|
||||
void UpdateFPExceptionsMaskForThreads()
|
||||
{
|
||||
int mask = -iszero(g_cvars.sys_float_exceptions);
|
||||
CONTEXT ctx;
|
||||
for (int i = 0; i < g_nDebugThreads; i++)
|
||||
{
|
||||
if (g_idDebugThreads[i] != GetCurrentThreadId())
|
||||
{
|
||||
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, TRUE, g_idDebugThreads[i]);
|
||||
ctx.ContextFlags = CONTEXT_ALL;
|
||||
SuspendThread(hThread);
|
||||
GetThreadContext(hThread, &ctx);
|
||||
#ifndef WIN64
|
||||
(ctx.FloatSave.ControlWord |= 7) &= ~5 | mask;
|
||||
(*(WORD*)(ctx.ExtendedRegisters + 24) |= 0x280) &= ~0x280 | mask;
|
||||
#else
|
||||
(ctx.FltSave.ControlWord |= 7) &= ~5 | mask;
|
||||
(ctx.FltSave.MxCsr |= 0x280) &= ~0x280 | mask;
|
||||
#endif
|
||||
SetThreadContext(hThread, &ctx);
|
||||
ResumeThread(hThread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int DebugCallStack::handleException(EXCEPTION_POINTERS* exception_pointer)
|
||||
{
|
||||
if (gEnv == NULL)
|
||||
{
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
ResetFPU(exception_pointer);
|
||||
|
||||
prev_sys_float_exceptions = 0;
|
||||
const int cached_sys_float_exceptions = g_cvars.sys_float_exceptions;
|
||||
|
||||
((CSystem*)gEnv->pSystem)->EnableFloatExceptions(0);
|
||||
|
||||
if (g_cvars.sys_WER)
|
||||
{
|
||||
gEnv->pLog->FlushAndClose();
|
||||
return CryEngineExceptionFilterWER(exception_pointer);
|
||||
}
|
||||
|
||||
if (g_cvars.sys_no_crash_dialog)
|
||||
{
|
||||
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
|
||||
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
|
||||
}
|
||||
|
||||
m_bCrash = true;
|
||||
|
||||
if (g_cvars.sys_no_crash_dialog)
|
||||
{
|
||||
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
|
||||
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
|
||||
}
|
||||
|
||||
static bool firstTime = true;
|
||||
|
||||
if (g_cvars.sys_dump_aux_threads)
|
||||
{
|
||||
for (int i = 0; i < g_nDebugThreads; i++)
|
||||
{
|
||||
if (g_idDebugThreads[i] != GetCurrentThreadId())
|
||||
{
|
||||
SuspendThread(OpenThread(THREAD_ALL_ACCESS, TRUE, g_idDebugThreads[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// uninstall our exception handler.
|
||||
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)prevExceptionHandler);
|
||||
|
||||
if (!firstTime)
|
||||
{
|
||||
WriteLineToLog("Critical Exception! Called Multiple Times!");
|
||||
gEnv->pLog->FlushAndClose();
|
||||
// Exception called more then once.
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
// Print exception info:
|
||||
{
|
||||
char excCode[80];
|
||||
char excAddr[80];
|
||||
WriteLineToLog("<CRITICAL EXCEPTION>");
|
||||
sprintf_s(excAddr, "0x%04X:0x%p", exception_pointer->ContextRecord->SegCs, exception_pointer->ExceptionRecord->ExceptionAddress);
|
||||
sprintf_s(excCode, "0x%08X", exception_pointer->ExceptionRecord->ExceptionCode);
|
||||
WriteLineToLog("Exception: %s, at Address: %s", excCode, excAddr);
|
||||
}
|
||||
|
||||
firstTime = false;
|
||||
|
||||
const int ret = SubmitBug(exception_pointer);
|
||||
|
||||
if (ret != IDB_IGNORE)
|
||||
{
|
||||
CryEngineExceptionFilterWER(exception_pointer);
|
||||
}
|
||||
|
||||
gEnv->pLog->FlushAndClose();
|
||||
|
||||
if (exception_pointer->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
|
||||
{
|
||||
// This is non continuable exception. abort application now.
|
||||
exit(exception_pointer->ExceptionRecord->ExceptionCode);
|
||||
}
|
||||
|
||||
//typedef long (__stdcall *ExceptionFunc)(EXCEPTION_POINTERS*);
|
||||
//ExceptionFunc prevFunc = (ExceptionFunc)prevExceptionHandler;
|
||||
//return prevFunc( (EXCEPTION_POINTERS*)exception_pointer );
|
||||
if (ret == IDB_EXIT)
|
||||
{
|
||||
// Immediate exit.
|
||||
// on windows, exit() and _exit() do all sorts of things, unfortuantely
|
||||
// TerminateProcess is the only way to die.
|
||||
TerminateProcess(GetCurrentProcess(), exception_pointer->ExceptionRecord->ExceptionCode); // we crashed, so don't return a zero exit code!
|
||||
// on linux based systems, _exit will not call ATEXIT and other things, which makes it more suitable for termination in an emergency such
|
||||
// as an unhandled exception.
|
||||
// however, this function is a windows exception handler.
|
||||
}
|
||||
else if (ret == IDB_IGNORE)
|
||||
{
|
||||
#ifndef WIN64
|
||||
exception_pointer->ContextRecord->FloatSave.StatusWord &= ~31;
|
||||
exception_pointer->ContextRecord->FloatSave.ControlWord |= 7;
|
||||
(*(WORD*)(exception_pointer->ContextRecord->ExtendedRegisters + 24) &= 31) |= 0x1F80;
|
||||
#else
|
||||
exception_pointer->ContextRecord->FltSave.StatusWord &= ~31;
|
||||
exception_pointer->ContextRecord->FltSave.ControlWord |= 7;
|
||||
(exception_pointer->ContextRecord->FltSave.MxCsr &= 31) |= 0x1F80;
|
||||
#endif
|
||||
firstTime = true;
|
||||
prevExceptionHandler = (void*)SetUnhandledExceptionFilter(CryUnhandledExceptionHandler);
|
||||
g_cvars.sys_float_exceptions = cached_sys_float_exceptions;
|
||||
((CSystem*)gEnv->pSystem)->EnableFloatExceptions(g_cvars.sys_float_exceptions);
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
// Continue;
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
void DebugCallStack::ReportBug(const char* szErrorMessage)
|
||||
{
|
||||
WriteLineToLog("Reporting bug: %s", szErrorMessage);
|
||||
|
||||
m_szBugMessage = szErrorMessage;
|
||||
m_context = CaptureCurrentContext();
|
||||
SubmitBug(NULL);
|
||||
m_szBugMessage = NULL;
|
||||
}
|
||||
|
||||
void DebugCallStack::dumpCallStack(std::vector<string>& funcs)
|
||||
{
|
||||
WriteLineToLog("=============================================================================");
|
||||
int len = (int)funcs.size();
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
const char* str = funcs[i].c_str();
|
||||
WriteLineToLog("%2d) %s", len - i, str);
|
||||
}
|
||||
WriteLineToLog("=============================================================================");
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
|
||||
{
|
||||
string path("");
|
||||
if ((gEnv) && (gEnv->pFileIO))
|
||||
{
|
||||
const char* logAlias = gEnv->pFileIO->GetAlias("@log@");
|
||||
if (!logAlias)
|
||||
{
|
||||
logAlias = gEnv->pFileIO->GetAlias("@root@");
|
||||
}
|
||||
if (logAlias)
|
||||
{
|
||||
path = logAlias;
|
||||
path += "/";
|
||||
}
|
||||
}
|
||||
|
||||
string fileName = path;
|
||||
fileName += "error.log";
|
||||
|
||||
struct stat fileInfo;
|
||||
string timeStamp;
|
||||
string backupPath;
|
||||
if (gEnv->IsDedicated())
|
||||
{
|
||||
backupPath = PathUtil::ToUnixPath(PathUtil::AddSlash(path + "DumpBackups"));
|
||||
gEnv->pFileIO->CreatePath(backupPath.c_str());
|
||||
|
||||
if (stat(fileName.c_str(), &fileInfo) == 0)
|
||||
{
|
||||
// Backup log
|
||||
tm creationTime;
|
||||
localtime_s(&creationTime, &fileInfo.st_mtime);
|
||||
char tempBuffer[32];
|
||||
strftime(tempBuffer, sizeof(tempBuffer), "%d %b %Y (%H %M %S)", &creationTime);
|
||||
timeStamp = tempBuffer;
|
||||
|
||||
string backupFileName = backupPath + timeStamp + " error.log";
|
||||
CopyFile(fileName.c_str(), backupFileName.c_str(), true);
|
||||
}
|
||||
}
|
||||
|
||||
FILE* f = nullptr;
|
||||
azfopen(&f, fileName.c_str(), "wt");
|
||||
|
||||
static char errorString[s_iCallStackSize];
|
||||
errorString[0] = 0;
|
||||
|
||||
// Time and Version.
|
||||
char versionbuf[1024];
|
||||
azstrcpy(versionbuf, AZ_ARRAY_SIZE(versionbuf), "");
|
||||
PutVersion(versionbuf, AZ_ARRAY_SIZE(versionbuf));
|
||||
cry_strcat(errorString, versionbuf);
|
||||
cry_strcat(errorString, "\n");
|
||||
|
||||
char excCode[MAX_WARNING_LENGTH];
|
||||
char excAddr[80];
|
||||
char desc[1024];
|
||||
char excDesc[MAX_WARNING_LENGTH];
|
||||
|
||||
// make sure the mouse cursor is visible
|
||||
ShowCursor(TRUE);
|
||||
|
||||
const char* excName;
|
||||
if (m_bIsFatalError || !pex)
|
||||
{
|
||||
const char* const szMessage = m_bIsFatalError ? s_szFatalErrorCode : m_szBugMessage;
|
||||
excName = szMessage;
|
||||
cry_strcpy(excCode, szMessage);
|
||||
cry_strcpy(excAddr, "");
|
||||
cry_strcpy(desc, "");
|
||||
cry_strcpy(m_excModule, "");
|
||||
cry_strcpy(excDesc, szMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(excAddr, "0x%04X:0x%p", pex->ContextRecord->SegCs, pex->ExceptionRecord->ExceptionAddress);
|
||||
sprintf_s(excCode, "0x%08X", pex->ExceptionRecord->ExceptionCode);
|
||||
excName = TranslateExceptionCode(pex->ExceptionRecord->ExceptionCode);
|
||||
cry_strcpy(desc, "");
|
||||
sprintf_s(excDesc, "%s\r\n%s", excName, desc);
|
||||
|
||||
|
||||
if (pex->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||
{
|
||||
if (pex->ExceptionRecord->NumberParameters > 1)
|
||||
{
|
||||
ULONG_PTR iswrite = pex->ExceptionRecord->ExceptionInformation[0];
|
||||
DWORD64 accessAddr = pex->ExceptionRecord->ExceptionInformation[1];
|
||||
if (iswrite)
|
||||
{
|
||||
sprintf_s(desc, "Attempt to write data to address 0x%08llu\r\nThe memory could not be \"written\"", accessAddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(desc, "Attempt to read from address 0x%08llu\r\nThe memory could not be \"read\"", accessAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WriteLineToLog("Exception Code: %s", excCode);
|
||||
WriteLineToLog("Exception Addr: %s", excAddr);
|
||||
WriteLineToLog("Exception Module: %s", m_excModule);
|
||||
WriteLineToLog("Exception Name : %s", excName);
|
||||
WriteLineToLog("Exception Description: %s", desc);
|
||||
|
||||
|
||||
cry_strcpy(m_excDesc, excDesc);
|
||||
cry_strcpy(m_excAddr, excAddr);
|
||||
cry_strcpy(m_excCode, excCode);
|
||||
|
||||
|
||||
char errs[32768];
|
||||
sprintf_s(errs, "Exception Code: %s\nException Addr: %s\nException Module: %s\nException Description: %s, %s\n",
|
||||
excCode, excAddr, m_excModule, excName, desc);
|
||||
|
||||
|
||||
cry_strcat(errs, "\nCall Stack Trace:\n");
|
||||
|
||||
std::vector<string> funcs;
|
||||
{
|
||||
AZ::Debug::StackFrame frames[25];
|
||||
AZ::Debug::SymbolStorage::StackLine lines[AZ_ARRAY_SIZE(frames)];
|
||||
unsigned int numFrames = AZ::Debug::StackRecorder::Record(frames, AZ_ARRAY_SIZE(frames), 3);
|
||||
if (numFrames)
|
||||
{
|
||||
AZ::Debug::SymbolStorage::DecodeFrames(frames, numFrames, lines);
|
||||
for (unsigned int i = 0; i < numFrames; i++)
|
||||
{
|
||||
funcs.push_back(lines[i]);
|
||||
}
|
||||
}
|
||||
dumpCallStack(funcs);
|
||||
// Fill call stack.
|
||||
char str[s_iCallStackSize];
|
||||
cry_strcpy(str, "");
|
||||
for (unsigned int i = 0; i < funcs.size(); i++)
|
||||
{
|
||||
char temp[s_iCallStackSize];
|
||||
sprintf_s(temp, "%2zd) %s", funcs.size() - i, (const char*)funcs[i].c_str());
|
||||
cry_strcat(str, temp);
|
||||
cry_strcat(str, "\r\n");
|
||||
cry_strcat(errs, temp);
|
||||
cry_strcat(errs, "\n");
|
||||
}
|
||||
cry_strcpy(m_excCallstack, str);
|
||||
}
|
||||
|
||||
cry_strcat(errorString, errs);
|
||||
|
||||
if (f)
|
||||
{
|
||||
fwrite(errorString, strlen(errorString), 1, f);
|
||||
{
|
||||
if (g_cvars.sys_dump_aux_threads)
|
||||
{
|
||||
for (int i = 0; i < g_nDebugThreads; i++)
|
||||
{
|
||||
if (g_idDebugThreads[i] != GetCurrentThreadId())
|
||||
{
|
||||
fprintf(f, "\n\nSuspended thread (%s):\n", g_nameDebugThreads[i]);
|
||||
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, TRUE, g_idDebugThreads[i]);
|
||||
|
||||
// mirrors the AZ::Debug::Trace::PrintCallstack() functionality, but prints to a file
|
||||
{
|
||||
AZ::Debug::StackFrame frames[10];
|
||||
|
||||
// Without StackFrame explicit alignment frames array is aligned to 4 bytes
|
||||
// which causes the stack tracing to fail.
|
||||
AZ::Debug::SymbolStorage::StackLine lines[AZ_ARRAY_SIZE(frames)];
|
||||
|
||||
unsigned int numFrames = AZ::Debug::StackRecorder::Record(frames, AZ_ARRAY_SIZE(frames), 0, hThread);
|
||||
if (numFrames)
|
||||
{
|
||||
AZ::Debug::SymbolStorage::DecodeFrames(frames, numFrames, lines);
|
||||
for (unsigned int i2 = 0; i2 < numFrames; ++i2)
|
||||
{
|
||||
fprintf(f, "%2d) %s\n", numFrames - i2, lines[i2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResumeThread(hThread);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fflush(f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
if (pex)
|
||||
{
|
||||
MINIDUMP_TYPE mdumpValue;
|
||||
bool bDump = true;
|
||||
switch (g_cvars.sys_dump_type)
|
||||
{
|
||||
case 0:
|
||||
bDump = false;
|
||||
break;
|
||||
case 1:
|
||||
mdumpValue = MiniDumpNormal;
|
||||
break;
|
||||
case 2:
|
||||
mdumpValue = (MINIDUMP_TYPE)(MiniDumpWithIndirectlyReferencedMemory | MiniDumpWithDataSegs);
|
||||
break;
|
||||
case 3:
|
||||
mdumpValue = MiniDumpWithFullMemory;
|
||||
break;
|
||||
default:
|
||||
mdumpValue = (MINIDUMP_TYPE)g_cvars.sys_dump_type;
|
||||
break;
|
||||
}
|
||||
if (bDump)
|
||||
{
|
||||
fileName = path + "error.dmp";
|
||||
|
||||
if (gEnv->IsDedicated() && stat(fileName.c_str(), &fileInfo) == 0)
|
||||
{
|
||||
// Backup dump (use timestamp from error.log if available)
|
||||
if (timeStamp.empty())
|
||||
{
|
||||
tm creationTime;
|
||||
localtime_s(&creationTime, &fileInfo.st_mtime);
|
||||
char tempBuffer[32];
|
||||
strftime(tempBuffer, sizeof(tempBuffer), "%d %b %Y (%H %M %S)", &creationTime);
|
||||
timeStamp = tempBuffer;
|
||||
}
|
||||
|
||||
string backupFileName = backupPath + timeStamp + " error.dmp";
|
||||
CopyFile(fileName.c_str(), backupFileName.c_str(), true);
|
||||
}
|
||||
|
||||
CryEngineExceptionFilterMiniDump(pex, fileName.c_str(), mdumpValue);
|
||||
}
|
||||
}
|
||||
|
||||
//if no crash dialog don't even submit the bug
|
||||
if (m_postBackupProcess && g_cvars.sys_no_crash_dialog == 0 && g_bUserDialog)
|
||||
{
|
||||
m_postBackupProcess();
|
||||
}
|
||||
else
|
||||
{
|
||||
// lawsonn: Disabling the JIRA-based crash reporter for now
|
||||
// we'll need to deal with it our own way, pending QA.
|
||||
// if you're customizing the engine this is also your opportunity to deal with it.
|
||||
if (g_cvars.sys_no_crash_dialog != 0 || !g_bUserDialog)
|
||||
{
|
||||
// ------------ place custom crash handler here ---------------------
|
||||
// it should launch an executable!
|
||||
/// by this time, error.bmp will be in the engine root folder
|
||||
// error.log and error.dmp will also be present in the engine root folder
|
||||
// if your error dumper wants those, it should zip them up and send them or offer to do so.
|
||||
// ------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
const bool bQuitting = !gEnv || !gEnv->pSystem || gEnv->pSystem->IsQuitting();
|
||||
|
||||
//[AlexMcC|16.04.10] When the engine is shutting down, MessageBox doesn't display a box
|
||||
// and immediately returns IDYES. Avoid this by just not trying to save if we're quitting.
|
||||
// Don't ask to save if this isn't a real crash (a real crash has exception pointers)
|
||||
if (g_cvars.sys_no_crash_dialog == 0 && g_bUserDialog && gEnv->IsEditor() && !bQuitting && pex)
|
||||
{
|
||||
BackupCurrentLevel();
|
||||
|
||||
const INT_PTR res = DialogBoxParam(gDLLHandle, MAKEINTRESOURCE(IDD_CONFIRM_SAVE_LEVEL), NULL, DebugCallStack::ConfirmSaveDialogProc, NULL);
|
||||
if (res == IDB_CONFIRM_SAVE)
|
||||
{
|
||||
if (SaveCurrentLevel())
|
||||
{
|
||||
MessageBox(NULL, "Level has been successfully saved!\r\nPress Ok to terminate Editor.", "Save", MB_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(NULL, "Error saving level.\r\nPress Ok to terminate Editor.", "Save", MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_cvars.sys_no_crash_dialog != 0 || !g_bUserDialog)
|
||||
{
|
||||
// terminate immediately - since we're in a crash, there is no point unwinding stack, we've already done access violation or worse.
|
||||
// calling exit will only cause further death down the line...
|
||||
TerminateProcess(GetCurrentProcess(), pex->ExceptionRecord->ExceptionCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INT_PTR CALLBACK DebugCallStack::ExceptionDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static EXCEPTION_POINTERS* pex;
|
||||
|
||||
static char errorString[32768] = "";
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
pex = (EXCEPTION_POINTERS*)lParam;
|
||||
HWND h;
|
||||
|
||||
if (pex->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
|
||||
{
|
||||
// Disable continue button for non continuable exceptions.
|
||||
//h = GetDlgItem( hwndDlg,IDB_CONTINUE );
|
||||
//if (h) EnableWindow( h,FALSE );
|
||||
}
|
||||
|
||||
DebugCallStack* pDCS = static_cast<DebugCallStack*>(DebugCallStack::instance());
|
||||
|
||||
h = GetDlgItem(hwndDlg, IDC_EXCEPTION_DESC);
|
||||
if (h)
|
||||
{
|
||||
SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excDesc);
|
||||
}
|
||||
|
||||
h = GetDlgItem(hwndDlg, IDC_EXCEPTION_CODE);
|
||||
if (h)
|
||||
{
|
||||
SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excCode);
|
||||
}
|
||||
|
||||
h = GetDlgItem(hwndDlg, IDC_EXCEPTION_MODULE);
|
||||
if (h)
|
||||
{
|
||||
SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excModule);
|
||||
}
|
||||
|
||||
h = GetDlgItem(hwndDlg, IDC_EXCEPTION_ADDRESS);
|
||||
if (h)
|
||||
{
|
||||
SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excAddr);
|
||||
}
|
||||
|
||||
// Fill call stack.
|
||||
HWND callStack = GetDlgItem(hwndDlg, IDC_CALLSTACK);
|
||||
if (callStack)
|
||||
{
|
||||
SendMessage(callStack, WM_SETTEXT, FALSE, (LPARAM)pDCS->m_excCallstack);
|
||||
}
|
||||
|
||||
if (hwndException)
|
||||
{
|
||||
DestroyWindow(hwndException);
|
||||
hwndException = 0;
|
||||
}
|
||||
|
||||
if (IsFloatingPointException(pex))
|
||||
{
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDB_IGNORE), TRUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDB_EXIT:
|
||||
case IDB_IGNORE:
|
||||
// Fall through.
|
||||
|
||||
EndDialog(hwndDlg, wParam);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK DebugCallStack::ConfirmSaveDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, [[maybe_unused]] LPARAM lParam)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
// The user might be holding down the spacebar while the engine crashes.
|
||||
// If we don't remove keyboard focus from this dialog, the keypress will
|
||||
// press the default button before the dialog actually appears, even if
|
||||
// the user has already released the key, which is bad.
|
||||
SetFocus(NULL);
|
||||
} break;
|
||||
case WM_COMMAND:
|
||||
{
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDB_CONFIRM_SAVE: // Fall through
|
||||
case IDB_DONT_SAVE:
|
||||
{
|
||||
EndDialog(hwndDlg, wParam);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool DebugCallStack::BackupCurrentLevel()
|
||||
{
|
||||
CSystem* pSystem = static_cast<CSystem*>(m_pSystem);
|
||||
if (pSystem && pSystem->GetUserCallback())
|
||||
{
|
||||
return pSystem->GetUserCallback()->OnBackupDocument();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebugCallStack::SaveCurrentLevel()
|
||||
{
|
||||
CSystem* pSystem = static_cast<CSystem*>(m_pSystem);
|
||||
if (pSystem && pSystem->GetUserCallback())
|
||||
{
|
||||
return pSystem->GetUserCallback()->OnSaveDocument();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int DebugCallStack::SubmitBug(EXCEPTION_POINTERS* exception_pointer)
|
||||
{
|
||||
int ret = IDB_EXIT;
|
||||
|
||||
assert(!hwndException);
|
||||
|
||||
RemoveOldFiles();
|
||||
|
||||
AZ::Debug::Trace::PrintCallstack("", 2);
|
||||
|
||||
LogExceptionInfo(exception_pointer);
|
||||
|
||||
if (IsFloatingPointException(exception_pointer))
|
||||
{
|
||||
//! Print exception dialog.
|
||||
ret = PrintException(exception_pointer);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DebugCallStack::ResetFPU(EXCEPTION_POINTERS* pex)
|
||||
{
|
||||
if (IsFloatingPointException(pex))
|
||||
{
|
||||
// How to reset FPU: http://www.experts-exchange.com/Programming/System/Windows__Programming/Q_10310953.html
|
||||
_clearfp();
|
||||
#ifndef WIN64
|
||||
pex->ContextRecord->FloatSave.ControlWord |= 0x2F;
|
||||
pex->ContextRecord->FloatSave.StatusWord &= ~0x8080;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
string DebugCallStack::GetModuleNameForAddr(void* addr)
|
||||
{
|
||||
if (m_modules.empty())
|
||||
{
|
||||
return "[unknown]";
|
||||
}
|
||||
|
||||
if (addr < m_modules.begin()->first)
|
||||
{
|
||||
return "[unknown]";
|
||||
}
|
||||
|
||||
TModules::const_iterator it = m_modules.begin();
|
||||
TModules::const_iterator end = m_modules.end();
|
||||
for (; ++it != end; )
|
||||
{
|
||||
if (addr < it->first)
|
||||
{
|
||||
return (--it)->second;
|
||||
}
|
||||
}
|
||||
|
||||
//if address is higher than the last module, we simply assume it is in the last module.
|
||||
return m_modules.rbegin()->second;
|
||||
}
|
||||
|
||||
void DebugCallStack::GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line)
|
||||
{
|
||||
AZ::Debug::SymbolStorage::StackLine func, file, module;
|
||||
AZ::Debug::SymbolStorage::FindFunctionFromIP(addr, &func, &file, &module, line, baseAddr);
|
||||
procName = func;
|
||||
filename = file;
|
||||
}
|
||||
|
||||
string DebugCallStack::GetCurrentFilename()
|
||||
{
|
||||
char fullpath[MAX_PATH_LENGTH + 1];
|
||||
GetModuleFileName(NULL, fullpath, MAX_PATH_LENGTH);
|
||||
return fullpath;
|
||||
}
|
||||
|
||||
static bool IsFloatingPointException(EXCEPTION_POINTERS* pex)
|
||||
{
|
||||
if (!pex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD exceptionCode = pex->ExceptionRecord->ExceptionCode;
|
||||
switch (exceptionCode)
|
||||
{
|
||||
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||
case EXCEPTION_FLT_INEXACT_RESULT:
|
||||
case EXCEPTION_FLT_INVALID_OPERATION:
|
||||
case EXCEPTION_FLT_OVERFLOW:
|
||||
case EXCEPTION_FLT_UNDERFLOW:
|
||||
case STATUS_FLOAT_MULTIPLE_FAULTS:
|
||||
case STATUS_FLOAT_MULTIPLE_TRAPS:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int DebugCallStack::PrintException(EXCEPTION_POINTERS* exception_pointer)
|
||||
{
|
||||
return (int)DialogBoxParam(gDLLHandle, MAKEINTRESOURCE(IDD_CRITICAL_ERROR), NULL, DebugCallStack::ExceptionDialogProc, (LPARAM)exception_pointer);
|
||||
}
|
||||
|
||||
#else
|
||||
void MarkThisThreadForDebugging(const char*) {}
|
||||
void UnmarkThisThreadFromDebugging() {}
|
||||
void UpdateFPExceptionsMaskForThreads() {}
|
||||
#endif //WIN32
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYSYSTEM_DEBUGCALLSTACK_H
|
||||
#define CRYINCLUDE_CRYSYSTEM_DEBUGCALLSTACK_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "IDebugCallStack.h"
|
||||
|
||||
#if defined (WIN32) || defined (WIN64)
|
||||
|
||||
//! Limits the maximal number of functions in call stack.
|
||||
const int MAX_DEBUG_STACK_ENTRIES_FILE_DUMP = 12;
|
||||
|
||||
struct ISystem;
|
||||
|
||||
//!============================================================================
|
||||
//!
|
||||
//! DebugCallStack class, capture call stack information from symbol files.
|
||||
//!
|
||||
//!============================================================================
|
||||
class DebugCallStack
|
||||
: public IDebugCallStack
|
||||
{
|
||||
public:
|
||||
DebugCallStack();
|
||||
virtual ~DebugCallStack();
|
||||
|
||||
ISystem* GetSystem() { return m_pSystem; };
|
||||
|
||||
virtual string GetModuleNameForAddr(void* addr);
|
||||
virtual void GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line);
|
||||
virtual string GetCurrentFilename();
|
||||
|
||||
void installErrorHandler(ISystem* pSystem);
|
||||
virtual int handleException(EXCEPTION_POINTERS* exception_pointer);
|
||||
|
||||
virtual void ReportBug(const char*);
|
||||
|
||||
void dumpCallStack(std::vector<string>& functions);
|
||||
|
||||
void SetUserDialogEnable(const bool bUserDialogEnable);
|
||||
|
||||
typedef std::map<void*, string> TModules;
|
||||
protected:
|
||||
static void RemoveOldFiles();
|
||||
static void RemoveFile(const char* szFileName);
|
||||
|
||||
static int PrintException(EXCEPTION_POINTERS* exception_pointer);
|
||||
static INT_PTR CALLBACK ExceptionDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
static INT_PTR CALLBACK ConfirmSaveDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void LogExceptionInfo(EXCEPTION_POINTERS* exception_pointer);
|
||||
bool BackupCurrentLevel();
|
||||
bool SaveCurrentLevel();
|
||||
int SubmitBug(EXCEPTION_POINTERS* exception_pointer);
|
||||
void ResetFPU(EXCEPTION_POINTERS* pex);
|
||||
|
||||
static const int s_iCallStackSize = 32768;
|
||||
|
||||
char m_excLine[256];
|
||||
char m_excModule[128];
|
||||
|
||||
char m_excDesc[MAX_WARNING_LENGTH];
|
||||
char m_excCode[MAX_WARNING_LENGTH];
|
||||
char m_excAddr[80];
|
||||
char m_excCallstack[s_iCallStackSize];
|
||||
|
||||
void* prevExceptionHandler;
|
||||
|
||||
bool m_bCrash;
|
||||
const char* m_szBugMessage;
|
||||
|
||||
ISystem* m_pSystem;
|
||||
|
||||
int m_nSkipNumFunctions;
|
||||
CONTEXT m_context;
|
||||
|
||||
TModules m_modules;
|
||||
};
|
||||
|
||||
#endif //WIN32
|
||||
|
||||
#endif // CRYINCLUDE_CRYSYSTEM_DEBUGCALLSTACK_H
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "CrySystem_precompiled.h"
|
||||
#include "System.h"
|
||||
#include <AZCrySystemInitLogSink.h>
|
||||
#include "DebugCallStack.h"
|
||||
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#undef AZ_RESTRICTED_SECTION
|
||||
@@ -87,6 +88,16 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar
|
||||
startupParams.pUserCallback->OnSystemConnect(pSystem);
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
// Environment Variable to signal we don't want to override our exception handler - our crash report system will set this
|
||||
auto envVar = AZ::Environment::FindVariable<bool>("ExceptionHandlerIsSet");
|
||||
const bool handlerIsSet = (envVar && *envVar);
|
||||
if (!handlerIsSet)
|
||||
{
|
||||
((DebugCallStack*)IDebugCallStack::instance())->installErrorHandler(pSystem);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool retVal = false;
|
||||
{
|
||||
AZ::Debug::StartupLogSinkReporter<AZ::Debug::CrySystemInitLogSink> initLogSink;
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : A multiplatform base class for handling errors and collecting call stacks
|
||||
|
||||
|
||||
#include "CrySystem_precompiled.h"
|
||||
#include "IDebugCallStack.h"
|
||||
#include "System.h"
|
||||
#include <AzFramework/IO/FileOperations.h>
|
||||
#include <AzCore/NativeUI/NativeUIRequests.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
//#if !defined(LINUX)
|
||||
|
||||
#include <ISystem.h>
|
||||
|
||||
const char* const IDebugCallStack::s_szFatalErrorCode = "FATAL_ERROR";
|
||||
|
||||
IDebugCallStack::IDebugCallStack()
|
||||
: m_bIsFatalError(false)
|
||||
, m_postBackupProcess(0)
|
||||
, m_memAllocFileHandle(AZ::IO::InvalidHandle)
|
||||
{
|
||||
}
|
||||
|
||||
IDebugCallStack::~IDebugCallStack()
|
||||
{
|
||||
StopMemLog();
|
||||
}
|
||||
|
||||
#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_SINGLETON
|
||||
IDebugCallStack* IDebugCallStack::instance()
|
||||
{
|
||||
static IDebugCallStack sInstance;
|
||||
return &sInstance;
|
||||
}
|
||||
#endif
|
||||
|
||||
void IDebugCallStack::FileCreationCallback(void (* postBackupProcess)())
|
||||
{
|
||||
m_postBackupProcess = postBackupProcess;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void IDebugCallStack::LogCallstack()
|
||||
{
|
||||
AZ::Debug::Trace::PrintCallstack("", 2);
|
||||
}
|
||||
|
||||
const char* IDebugCallStack::TranslateExceptionCode(DWORD dwExcept)
|
||||
{
|
||||
switch (dwExcept)
|
||||
{
|
||||
#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_TRANSLATE
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
return "EXCEPTION_ACCESS_VIOLATION";
|
||||
break;
|
||||
case EXCEPTION_DATATYPE_MISALIGNMENT:
|
||||
return "EXCEPTION_DATATYPE_MISALIGNMENT";
|
||||
break;
|
||||
case EXCEPTION_BREAKPOINT:
|
||||
return "EXCEPTION_BREAKPOINT";
|
||||
break;
|
||||
case EXCEPTION_SINGLE_STEP:
|
||||
return "EXCEPTION_SINGLE_STEP";
|
||||
break;
|
||||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
|
||||
return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
|
||||
break;
|
||||
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
||||
return "EXCEPTION_FLT_DENORMAL_OPERAND";
|
||||
break;
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||
return "EXCEPTION_FLT_DIVIDE_BY_ZERO";
|
||||
break;
|
||||
case EXCEPTION_FLT_INEXACT_RESULT:
|
||||
return "EXCEPTION_FLT_INEXACT_RESULT";
|
||||
break;
|
||||
case EXCEPTION_FLT_INVALID_OPERATION:
|
||||
return "EXCEPTION_FLT_INVALID_OPERATION";
|
||||
break;
|
||||
case EXCEPTION_FLT_OVERFLOW:
|
||||
return "EXCEPTION_FLT_OVERFLOW";
|
||||
break;
|
||||
case EXCEPTION_FLT_STACK_CHECK:
|
||||
return "EXCEPTION_FLT_STACK_CHECK";
|
||||
break;
|
||||
case EXCEPTION_FLT_UNDERFLOW:
|
||||
return "EXCEPTION_FLT_UNDERFLOW";
|
||||
break;
|
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
||||
return "EXCEPTION_INT_DIVIDE_BY_ZERO";
|
||||
break;
|
||||
case EXCEPTION_INT_OVERFLOW:
|
||||
return "EXCEPTION_INT_OVERFLOW";
|
||||
break;
|
||||
case EXCEPTION_PRIV_INSTRUCTION:
|
||||
return "EXCEPTION_PRIV_INSTRUCTION";
|
||||
break;
|
||||
case EXCEPTION_IN_PAGE_ERROR:
|
||||
return "EXCEPTION_IN_PAGE_ERROR";
|
||||
break;
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||
return "EXCEPTION_ILLEGAL_INSTRUCTION";
|
||||
break;
|
||||
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
|
||||
return "EXCEPTION_NONCONTINUABLE_EXCEPTION";
|
||||
break;
|
||||
case EXCEPTION_STACK_OVERFLOW:
|
||||
return "EXCEPTION_STACK_OVERFLOW";
|
||||
break;
|
||||
case EXCEPTION_INVALID_DISPOSITION:
|
||||
return "EXCEPTION_INVALID_DISPOSITION";
|
||||
break;
|
||||
case EXCEPTION_GUARD_PAGE:
|
||||
return "EXCEPTION_GUARD_PAGE";
|
||||
break;
|
||||
case EXCEPTION_INVALID_HANDLE:
|
||||
return "EXCEPTION_INVALID_HANDLE";
|
||||
break;
|
||||
//case EXCEPTION_POSSIBLE_DEADLOCK: return "EXCEPTION_POSSIBLE_DEADLOCK"; break ;
|
||||
|
||||
case STATUS_FLOAT_MULTIPLE_FAULTS:
|
||||
return "STATUS_FLOAT_MULTIPLE_FAULTS";
|
||||
break;
|
||||
case STATUS_FLOAT_MULTIPLE_TRAPS:
|
||||
return "STATUS_FLOAT_MULTIPLE_TRAPS";
|
||||
break;
|
||||
|
||||
|
||||
#endif
|
||||
default:
|
||||
return "Unknown";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void IDebugCallStack::PutVersion(char* str, size_t length)
|
||||
{
|
||||
AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option")
|
||||
|
||||
if (!gEnv || !gEnv->pSystem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char sFileVersion[128];
|
||||
gEnv->pSystem->GetFileVersion().ToString(sFileVersion, sizeof(sFileVersion));
|
||||
|
||||
char sProductVersion[128];
|
||||
gEnv->pSystem->GetProductVersion().ToString(sProductVersion, sizeof(sFileVersion));
|
||||
|
||||
|
||||
//! Get time.
|
||||
time_t ltime;
|
||||
time(<ime);
|
||||
tm* today = localtime(<ime);
|
||||
|
||||
char s[1024];
|
||||
//! Use strftime to build a customized time string.
|
||||
strftime(s, 128, "Logged at %#c\n", today);
|
||||
azstrcat(str, length, s);
|
||||
sprintf_s(s, "FileVersion: %s\n", sFileVersion);
|
||||
azstrcat(str, length, s);
|
||||
sprintf_s(s, "ProductVersion: %s\n", sProductVersion);
|
||||
azstrcat(str, length, s);
|
||||
|
||||
if (gEnv->pLog)
|
||||
{
|
||||
const char* logfile = gEnv->pLog->GetFileName();
|
||||
if (logfile)
|
||||
{
|
||||
sprintf (s, "LogFile: %s\n", logfile);
|
||||
azstrcat(str, length, s);
|
||||
}
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
|
||||
azstrcat(str, length, "ProjectDir: ");
|
||||
azstrcat(str, length, projectPath.c_str());
|
||||
azstrcat(str, length, "\n");
|
||||
|
||||
#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_APPEND_MODULENAME
|
||||
GetModuleFileNameA(NULL, s, sizeof(s));
|
||||
|
||||
// Log EXE filename only if possible (not full EXE path which could contain sensitive info)
|
||||
AZStd::string exeName;
|
||||
if (AZ::StringFunc::Path::GetFullFileName(s, exeName))
|
||||
{
|
||||
azstrcat(str, length, "Executable: ");
|
||||
azstrcat(str, length, exeName.c_str());
|
||||
|
||||
# ifdef AZ_DEBUG_BUILD
|
||||
azstrcat(str, length, " (debug: yes");
|
||||
# else
|
||||
azstrcat(str, length, " (debug: no");
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
AZ_POP_DISABLE_WARNING
|
||||
}
|
||||
|
||||
|
||||
//Crash the application, in this way the debug callstack routine will be called and it will create all the necessary files (error.log, dump, and eventually screenshot)
|
||||
void IDebugCallStack::FatalError(const char* description)
|
||||
{
|
||||
m_bIsFatalError = true;
|
||||
WriteLineToLog(description);
|
||||
|
||||
#ifndef _RELEASE
|
||||
bool bShowDebugScreen = g_cvars.sys_no_crash_dialog == 0;
|
||||
// showing the debug screen is not safe when not called from mainthread
|
||||
// it normally leads to a infinity recursion followed by a stack overflow, preventing
|
||||
// useful call stacks, thus they are disabled
|
||||
bShowDebugScreen = bShowDebugScreen && gEnv->mMainThreadId == CryGetCurrentThreadId();
|
||||
if (bShowDebugScreen)
|
||||
{
|
||||
EBUS_EVENT(AZ::NativeUI::NativeUIRequestBus, DisplayOkDialog, "Open 3D Engine Fatal Error", description, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || !defined(_RELEASE)
|
||||
int* p = 0x0;
|
||||
PREFAST_SUPPRESS_WARNING(6011) * p = 1; // we're intentionally crashing here
|
||||
#endif
|
||||
}
|
||||
|
||||
void IDebugCallStack::WriteLineToLog(const char* format, ...)
|
||||
{
|
||||
va_list ArgList;
|
||||
char szBuffer[MAX_WARNING_LENGTH];
|
||||
va_start(ArgList, format);
|
||||
vsnprintf_s(szBuffer, sizeof(szBuffer), sizeof(szBuffer) - 1, format, ArgList);
|
||||
cry_strcat(szBuffer, "\n");
|
||||
szBuffer[sizeof(szBuffer) - 1] = '\0';
|
||||
va_end(ArgList);
|
||||
|
||||
AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle;
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Open("@Log@\\error.log", AZ::IO::GetOpenModeFromStringMode("a+t"), fileHandle);
|
||||
if (fileHandle != AZ::IO::InvalidHandle)
|
||||
{
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Write(fileHandle, szBuffer, strlen(szBuffer));
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Flush(fileHandle);
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Close(fileHandle);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void IDebugCallStack::StartMemLog()
|
||||
{
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Open("@Log@\\memallocfile.log", AZ::IO::OpenMode::ModeWrite, m_memAllocFileHandle);
|
||||
|
||||
assert(m_memAllocFileHandle != AZ::IO::InvalidHandle);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void IDebugCallStack::StopMemLog()
|
||||
{
|
||||
if (m_memAllocFileHandle != AZ::IO::InvalidHandle)
|
||||
{
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Close(m_memAllocFileHandle);
|
||||
m_memAllocFileHandle = AZ::IO::InvalidHandle;
|
||||
}
|
||||
}
|
||||
//#endif //!defined(LINUX)
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : A multiplatform base class for handling errors and collecting call stacks
|
||||
|
||||
#ifndef CRYINCLUDE_CRYSYSTEM_IDEBUGCALLSTACK_H
|
||||
#define CRYINCLUDE_CRYSYSTEM_IDEBUGCALLSTACK_H
|
||||
#pragma once
|
||||
|
||||
#include "System.h"
|
||||
|
||||
#if AZ_LEGACY_CRYSYSTEM_TRAIT_FORWARD_EXCEPTION_POINTERS
|
||||
struct EXCEPTION_POINTERS;
|
||||
#endif
|
||||
//! Limits the maximal number of functions in call stack.
|
||||
enum
|
||||
{
|
||||
MAX_DEBUG_STACK_ENTRIES = 80
|
||||
};
|
||||
|
||||
class IDebugCallStack
|
||||
{
|
||||
public:
|
||||
// Returns single instance of DebugStack
|
||||
static IDebugCallStack* instance();
|
||||
|
||||
virtual int handleException([[maybe_unused]] EXCEPTION_POINTERS* exception_pointer){return 0; }
|
||||
|
||||
// returns the module name of a given address
|
||||
virtual string GetModuleNameForAddr([[maybe_unused]] void* addr) { return "[unknown]"; }
|
||||
|
||||
// returns the function name of a given address together with source file and line number (if available) of a given address
|
||||
virtual void GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line)
|
||||
{
|
||||
filename = "[unknown]";
|
||||
line = 0;
|
||||
baseAddr = addr;
|
||||
#if defined(PLATFORM_64BIT)
|
||||
procName.Format("[%016llX]", addr);
|
||||
#else
|
||||
procName.Format("[%08X]", addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
// returns current filename
|
||||
virtual string GetCurrentFilename() { return "[unknown]"; }
|
||||
|
||||
//! Dumps Current Call Stack to log.
|
||||
virtual void LogCallstack();
|
||||
//triggers a fatal error, so the DebugCallstack can create the error.log and terminate the application
|
||||
void FatalError(const char*);
|
||||
|
||||
//Reports a bug and continues execution
|
||||
virtual void ReportBug(const char*) {}
|
||||
|
||||
virtual void FileCreationCallback(void (* postBackupProcess)());
|
||||
|
||||
static void WriteLineToLog(const char* format, ...);
|
||||
|
||||
virtual void StartMemLog();
|
||||
virtual void StopMemLog();
|
||||
|
||||
protected:
|
||||
IDebugCallStack();
|
||||
virtual ~IDebugCallStack();
|
||||
|
||||
static const char* TranslateExceptionCode(DWORD dwExcept);
|
||||
static void PutVersion(char* str, size_t length);
|
||||
|
||||
bool m_bIsFatalError;
|
||||
static const char* const s_szFatalErrorCode;
|
||||
|
||||
void (* m_postBackupProcess)();
|
||||
|
||||
AZ::IO::HandleType m_memAllocFileHandle;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYSYSTEM_IDEBUGCALLSTACK_H
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "IMovieSystem.h"
|
||||
#include <ILocalizationManager.h>
|
||||
#include "CryPath.h"
|
||||
#include <Pak/CryPakUtils.h>
|
||||
|
||||
#include <LoadScreenBus.h>
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
#include <locale.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "CryZlib.h"
|
||||
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <ISystem.h>
|
||||
#include "System.h"
|
||||
#include "CryPath.h" // PathUtil::ReplaceExtension()
|
||||
#include <Pak/CryPakUtils.h>
|
||||
#include "UnicodeFunctions.h"
|
||||
|
||||
#include <AzFramework/IO/FileOperations.h>
|
||||
@@ -237,7 +236,6 @@ void CLog::CloseLogFile([[maybe_unused]] bool forceClose)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
AZ::IO::HandleType CLog::OpenLogFile(const char* filename, const char* mode)
|
||||
{
|
||||
CDebugAllowFileAccess ignoreInvalidFileAccess;
|
||||
using namespace AZ::IO;
|
||||
|
||||
AZ_Assert(m_logFileHandle == AZ::IO::InvalidHandle, "Attempt to open log file when one is already open. This would lead to a handle leak.");
|
||||
@@ -1116,8 +1114,6 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
|
||||
|
||||
if (logToFile)
|
||||
{
|
||||
CDebugAllowFileAccess dafa;
|
||||
|
||||
if (m_logFileHandle == AZ::IO::InvalidHandle)
|
||||
{
|
||||
OpenLogFile(m_szFilename, "w+t");
|
||||
|
||||
@@ -208,6 +208,7 @@ struct SSystemCVars
|
||||
int sys_no_crash_dialog;
|
||||
int sys_no_error_report_window;
|
||||
int sys_dump_aux_threads;
|
||||
int sys_WER;
|
||||
int sys_dump_type;
|
||||
int sys_ai;
|
||||
int sys_entitysystem;
|
||||
|
||||
@@ -91,7 +91,6 @@
|
||||
#include <HMDBus.h>
|
||||
|
||||
#include <AzFramework/Archive/Archive.h>
|
||||
#include <Pak/CryPakUtils.h>
|
||||
#include "XConsole.h"
|
||||
#include "Log.h"
|
||||
#include "XML/xml.h"
|
||||
@@ -122,6 +121,10 @@
|
||||
# include <AzFramework/Network/AssetProcessorConnection.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers);
|
||||
#endif
|
||||
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_14
|
||||
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
|
||||
@@ -1480,6 +1483,13 @@ AZ_POP_DISABLE_WARNING
|
||||
|
||||
InlineInitializationProcessing("CSystem::Init LoadConfigurations");
|
||||
|
||||
#ifdef WIN32
|
||||
if (g_cvars.sys_WER)
|
||||
{
|
||||
SetUnhandledExceptionFilter(CryEngineExceptionFilterWER);
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Localization
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -2016,6 +2026,14 @@ void CSystem::CreateSystemVars()
|
||||
REGISTER_CVAR2("sys_update_profile_time", &g_cvars.sys_update_profile_time, 1.0f, 0, "Time to keep updates timings history for.");
|
||||
REGISTER_CVAR2("sys_no_crash_dialog", &g_cvars.sys_no_crash_dialog, m_bNoCrashDialog, VF_NULL, "Whether to disable the crash dialog window");
|
||||
REGISTER_CVAR2("sys_no_error_report_window", &g_cvars.sys_no_error_report_window, m_bNoErrorReportWindow, VF_NULL, "Whether to disable the error report list");
|
||||
#if defined(_RELEASE)
|
||||
if (!gEnv->IsDedicated())
|
||||
{
|
||||
REGISTER_CVAR2("sys_WER", &g_cvars.sys_WER, 1, 0, "Enables Windows Error Reporting");
|
||||
}
|
||||
#else
|
||||
REGISTER_CVAR2("sys_WER", &g_cvars.sys_WER, 0, 0, "Enables Windows Error Reporting");
|
||||
#endif
|
||||
|
||||
#ifdef USE_HTTP_WEBSOCKETS
|
||||
REGISTER_CVAR2("sys_simple_http_base_port", &g_cvars.sys_simple_http_base_port, 1880, VF_REQUIRE_APP_RESTART,
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#include "IDebugCallStack.h"
|
||||
|
||||
#if defined(APPLE) || defined(LINUX)
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
@@ -355,6 +357,7 @@ void CSystem::FatalError(const char* format, ...)
|
||||
}
|
||||
|
||||
// Dump callstack.
|
||||
IDebugCallStack::instance()->FatalError(szBuffer);
|
||||
#endif
|
||||
|
||||
CryDebugBreak();
|
||||
@@ -396,6 +399,8 @@ void CSystem::ReportBug([[maybe_unused]] const char* format, ...)
|
||||
va_start(ArgList, format);
|
||||
azvsnprintf(szBuffer + strlen(sPrefix), MAX_WARNING_LENGTH - strlen(sPrefix), format, ArgList);
|
||||
va_end(ArgList);
|
||||
|
||||
IDebugCallStack::instance()->ReportBug(szBuffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Support for Windows Error Reporting (WER)
|
||||
|
||||
|
||||
#include "CrySystem_precompiled.h"
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#include "System.h"
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include "errorrep.h"
|
||||
#include "ISystem.h"
|
||||
|
||||
#include <DbgHelp.h>
|
||||
|
||||
static WCHAR szPath[MAX_PATH + 1];
|
||||
static WCHAR szFR[] = L"\\System32\\FaultRep.dll";
|
||||
|
||||
WCHAR* GetFullPathToFaultrepDll(void)
|
||||
{
|
||||
UINT rc = GetSystemWindowsDirectoryW(szPath, ARRAYSIZE(szPath));
|
||||
if (rc == 0 || rc > ARRAYSIZE(szPath) - ARRAYSIZE(szFR) - 1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wcscat_s(szPath, szFR);
|
||||
return szPath;
|
||||
}
|
||||
|
||||
|
||||
typedef BOOL (WINAPI * MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType,
|
||||
CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
|
||||
CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
|
||||
CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
LONG WINAPI CryEngineExceptionFilterMiniDump(struct _EXCEPTION_POINTERS* pExceptionPointers, const char* szDumpPath, MINIDUMP_TYPE DumpType)
|
||||
{
|
||||
// note: In debug mode, this dll is loaded on startup anyway, so this should not incur an additional load unless it crashes
|
||||
// very early during startup.
|
||||
|
||||
fflush(nullptr); // according to MSDN on fflush, calling fflush on null flushes all buffers.
|
||||
HMODULE hndDBGHelpDLL = LoadLibraryA("DBGHELP.DLL");
|
||||
|
||||
if (!hndDBGHelpDLL)
|
||||
{
|
||||
CryLogAlways("Failed to record DMP file: Could not open DBGHELP.DLL");
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
MINIDUMPWRITEDUMP dumpFnPtr = (MINIDUMPWRITEDUMP)::GetProcAddress(hndDBGHelpDLL, "MiniDumpWriteDump");
|
||||
if (!dumpFnPtr)
|
||||
{
|
||||
CryLogAlways("Failed to record DMP file: Unable to find MiniDumpWriteDump in DBGHELP.DLL");
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
HANDLE hFile = ::CreateFile(szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CryLogAlways("Failed to record DMP file: could not open file '%s' for writing - error code: %d", szDumpPath, GetLastError());
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
_MINIDUMP_EXCEPTION_INFORMATION ExInfo;
|
||||
ExInfo.ThreadId = ::GetCurrentThreadId();
|
||||
ExInfo.ExceptionPointers = pExceptionPointers;
|
||||
ExInfo.ClientPointers = NULL;
|
||||
|
||||
BOOL bOK = dumpFnPtr(GetCurrentProcess(), GetCurrentProcessId(), hFile, DumpType, &ExInfo, NULL, NULL);
|
||||
::CloseHandle(hFile);
|
||||
|
||||
if (bOK)
|
||||
{
|
||||
CryLogAlways("Successfully recorded DMP file: '%s'", szDumpPath);
|
||||
return EXCEPTION_EXECUTE_HANDLER; // SUCCESS! you can execute your handlers now
|
||||
}
|
||||
else
|
||||
{
|
||||
CryLogAlways("Failed to record DMP file: '%s' - error code: %d", szDumpPath, GetLastError());
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers)
|
||||
{
|
||||
if (g_cvars.sys_WER > 1)
|
||||
{
|
||||
char szScratch [_MAX_PATH];
|
||||
const char* szDumpPath = gEnv->pCryPak->AdjustFileName("@log@/CE2Dump.dmp", szScratch, AZ_ARRAY_SIZE(szScratch), 0);
|
||||
|
||||
MINIDUMP_TYPE mdumpValue = (MINIDUMP_TYPE)(MiniDumpNormal);
|
||||
if (g_cvars.sys_WER > 1)
|
||||
{
|
||||
mdumpValue = (MINIDUMP_TYPE)(g_cvars.sys_WER - 2);
|
||||
}
|
||||
|
||||
return CryEngineExceptionFilterMiniDump(pExceptionPointers, szDumpPath, mdumpValue);
|
||||
}
|
||||
|
||||
LONG lRet = EXCEPTION_CONTINUE_SEARCH;
|
||||
WCHAR* psz = GetFullPathToFaultrepDll();
|
||||
if (psz)
|
||||
{
|
||||
HMODULE hFaultRepDll = LoadLibraryW(psz);
|
||||
if (hFaultRepDll)
|
||||
{
|
||||
pfn_REPORTFAULT pfn = (pfn_REPORTFAULT)GetProcAddress(hFaultRepDll, "ReportFault");
|
||||
if (pfn)
|
||||
{
|
||||
pfn(pExceptionPointers, 0);
|
||||
lRet = EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
FreeLibrary(hFaultRepDll);
|
||||
}
|
||||
}
|
||||
return lRet;
|
||||
}
|
||||
|
||||
#endif // WIN32
|
||||
@@ -15,6 +15,8 @@ set(FILES
|
||||
CmdLineArg.cpp
|
||||
ConsoleBatchFile.cpp
|
||||
ConsoleHelpGen.cpp
|
||||
DebugCallStack.cpp
|
||||
IDebugCallStack.cpp
|
||||
Log.cpp
|
||||
System.cpp
|
||||
SystemCFG.cpp
|
||||
@@ -31,6 +33,8 @@ set(FILES
|
||||
CmdLineArg.h
|
||||
ConsoleBatchFile.h
|
||||
ConsoleHelpGen.h
|
||||
DebugCallStack.h
|
||||
IDebugCallStack.h
|
||||
Log.h
|
||||
SimpleStringPool.h
|
||||
CrySystem_precompiled.h
|
||||
@@ -72,4 +76,5 @@ set(FILES
|
||||
ViewSystem/ViewSystem.cpp
|
||||
ViewSystem/ViewSystem.h
|
||||
CrySystem_precompiled.cpp
|
||||
WindowsErrorReporting.cpp
|
||||
)
|
||||
|
||||
@@ -20,10 +20,12 @@
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
//! Simple class for verifying that no concurrent access is occuring.
|
||||
//! Simple class for verifying that no concurrent access is occurring.
|
||||
//! This is *not* a synchronization primitive, and is intended simply for checking that no concurrency issues exist.
|
||||
//! It will be compiled out in release builds.
|
||||
//! Use concurrency_checker like a mutex (i.e. call soft_lock() and soft_unlock() around all instances of your data access).
|
||||
//! Use soft_lock_shared and soft_unlock_shared around places where multiple threads are allowed to have read access
|
||||
//! at the same time as long as nothing else already has a soft lock
|
||||
//! It will assert if there are multiple threads accessing the locked code/data at the same time.
|
||||
//! Expected use case is for defensive programming: when you do not expect any concurrent access within a system,
|
||||
//! but want to verify that it stays that way in the future, without incurring the overhead of a mutex.
|
||||
@@ -34,7 +36,7 @@ namespace AZStd
|
||||
{
|
||||
#ifdef AZ_CONCURRENCY_CHECKER_ENABLED
|
||||
uint32_t count = ++m_concurrencyCounter;
|
||||
AZ_Assert(count == 1, "Concurrency check failed. Multiple threads are trying to access data at the same time, or there is a lock/unlock mismatch.");
|
||||
AZ_Assert(count == 1 && m_sharedConcurrencyCounter == 0, "Concurrency check failed. Multiple threads are trying to access data at the same time, or there is a lock/unlock mismatch.");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -46,9 +48,27 @@ namespace AZStd
|
||||
#endif
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE void soft_lock_shared()
|
||||
{
|
||||
#ifdef AZ_CONCURRENCY_CHECKER_ENABLED
|
||||
AZ_Assert(m_concurrencyCounter == 0, "Concurrency check failed. A soft_lock_shared was attempted when there was already a soft_lock.");
|
||||
++m_sharedConcurrencyCounter;
|
||||
#endif
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE void soft_unlock_shared()
|
||||
{
|
||||
#ifdef AZ_CONCURRENCY_CHECKER_ENABLED
|
||||
AZ_Assert(m_sharedConcurrencyCounter != 0, "Concurrency check failed. There is a shared_lock/shared_unlock mismatch.");
|
||||
--m_sharedConcurrencyCounter;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
#ifdef AZ_CONCURRENCY_CHECKER_ENABLED
|
||||
AZStd::atomic_uint32_t m_concurrencyCounter = 0;
|
||||
AZStd::atomic_uint32_t m_sharedConcurrencyCounter = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -293,15 +293,12 @@ namespace UnitTest
|
||||
{
|
||||
array_view<int> view({ 1,2,3,4 });
|
||||
|
||||
UnitTest::TestRunner::Instance().StartAssertTests();
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
|
||||
EXPECT_EQ(0, UnitTest::TestRunner::Instance().m_numAssertsFailed);
|
||||
view[4];
|
||||
EXPECT_EQ(1, UnitTest::TestRunner::Instance().m_numAssertsFailed);
|
||||
view[5];
|
||||
EXPECT_EQ(2, UnitTest::TestRunner::Instance().m_numAssertsFailed);
|
||||
|
||||
UnitTest::TestRunner::Instance().StopAssertTests();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AtomCore/std/parallel/concurrency_checker.h>
|
||||
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
using namespace AZStd;
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class ConcurrencyCheckerTestFixture
|
||||
: public AllocatorsTestFixture
|
||||
{
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
AllocatorsFixture::SetUp();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(AllocatorsTestFixture, SoftLock_NoContention_NoAsserts)
|
||||
{
|
||||
concurrency_checker concurrencyChecker;
|
||||
concurrencyChecker.soft_lock();
|
||||
concurrencyChecker.soft_unlock();
|
||||
concurrencyChecker.soft_lock();
|
||||
concurrencyChecker.soft_unlock();
|
||||
}
|
||||
|
||||
TEST_F(AllocatorsTestFixture, SoftLock_AlreadyLocked_Assert)
|
||||
{
|
||||
concurrency_checker concurrencyChecker;
|
||||
concurrencyChecker.soft_lock();
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
concurrencyChecker.soft_lock();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
|
||||
TEST_F(AllocatorsTestFixture, SoftUnlock_NotAlreadyLocked_Assert)
|
||||
{
|
||||
concurrency_checker concurrencyChecker;
|
||||
concurrencyChecker.soft_lock();
|
||||
concurrencyChecker.soft_unlock();
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
concurrencyChecker.soft_unlock();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
|
||||
TEST_F(AllocatorsTestFixture, SoftLockShared_NoContention_NoAsserts)
|
||||
{
|
||||
concurrency_checker concurrencyChecker;
|
||||
// Multiple shared locks can be made at once,
|
||||
// as long as they are all unlocked before the next soft_lock
|
||||
concurrencyChecker.soft_lock_shared();
|
||||
concurrencyChecker.soft_lock_shared();
|
||||
concurrencyChecker.soft_unlock_shared();
|
||||
concurrencyChecker.soft_unlock_shared();
|
||||
|
||||
concurrencyChecker.soft_lock();
|
||||
concurrencyChecker.soft_unlock();
|
||||
|
||||
concurrencyChecker.soft_lock_shared();
|
||||
concurrencyChecker.soft_lock_shared();
|
||||
concurrencyChecker.soft_unlock_shared();
|
||||
concurrencyChecker.soft_unlock_shared();
|
||||
|
||||
concurrencyChecker.soft_lock();
|
||||
concurrencyChecker.soft_unlock();
|
||||
}
|
||||
|
||||
TEST_F(AllocatorsTestFixture, SoftLockShared_SharedLockAfterSoftLock_Assert)
|
||||
{
|
||||
concurrency_checker concurrencyChecker;
|
||||
|
||||
concurrencyChecker.soft_lock();
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
concurrencyChecker.soft_lock_shared();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
|
||||
TEST_F(AllocatorsTestFixture, SoftUnlockShared_NotAlreadyLocked_Assert)
|
||||
{
|
||||
concurrency_checker concurrencyChecker;
|
||||
concurrencyChecker.soft_lock_shared();
|
||||
concurrencyChecker.soft_unlock_shared();
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
concurrencyChecker.soft_unlock_shared();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
set(FILES
|
||||
ArrayView.cpp
|
||||
ConcurrencyCheckerTests.cpp
|
||||
InstanceDatabase.cpp
|
||||
JsonSerializationUtilsTests.cpp
|
||||
lru_cache.cpp
|
||||
|
||||
@@ -307,6 +307,8 @@ namespace AZ
|
||||
Asset(AssetLoadBehavior loadBehavior = AssetLoadBehavior::Default);
|
||||
/// Create an asset from a valid asset data (created asset), might not be loaded or currently loading.
|
||||
Asset(AssetData* assetData, AssetLoadBehavior loadBehavior);
|
||||
/// Create an asset from a valid asset data (created asset) and set the asset id for both, might not be loaded or currently loading.
|
||||
Asset(const AZ::Data::AssetId& id, AssetData* assetData, AssetLoadBehavior loadBehavior);
|
||||
/// Initialize asset pointer with id, type, and hint. No data construction will occur until QueueLoad is called.
|
||||
Asset(const AZ::Data::AssetId& id, const AZ::Data::AssetType& type, const AZStd::string& hint = AZStd::string());
|
||||
|
||||
@@ -787,6 +789,18 @@ namespace AZ
|
||||
SetData(assetData);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
template<class T>
|
||||
Asset<T>::Asset(const AssetId& id, AssetData* assetData, AssetLoadBehavior loadBehavior)
|
||||
: m_assetId(id)
|
||||
, m_assetType(azrtti_typeid<T>())
|
||||
, m_loadBehavior(loadBehavior)
|
||||
{
|
||||
AZ_Assert(!assetData->m_assetId.IsValid(), "Asset data already has an ID set.");
|
||||
assetData->m_assetId = id;
|
||||
SetData(assetData);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
template<class T>
|
||||
Asset<T>::Asset(const AssetId& id, const AZ::Data::AssetType& type, const AZStd::string& hint)
|
||||
|
||||
@@ -133,7 +133,15 @@ namespace AZ
|
||||
if (!id.m_guid.IsNull())
|
||||
{
|
||||
*instance = AssetManager::Instance().FindOrCreateAsset(id, instance->GetType(), instance->GetAutoLoadBehavior());
|
||||
|
||||
if (!instance->GetId().IsValid())
|
||||
{
|
||||
// If the asset failed to be created, FindOrCreateAsset returns an asset instance with a null
|
||||
// id. To preserve the asset id in the source json, reset the asset to an empty one, but with
|
||||
// the right id.
|
||||
const auto loadBehavior = instance->GetAutoLoadBehavior();
|
||||
*instance = Asset<AssetData>(id, instance->GetType());
|
||||
instance->SetAutoLoadBehavior(loadBehavior);
|
||||
}
|
||||
|
||||
result.Combine(context.Report(result, "Successfully created Asset<T> with id."));
|
||||
}
|
||||
|
||||
@@ -287,71 +287,28 @@ namespace AZ
|
||||
|
||||
//! Scale modifiers
|
||||
//! @{
|
||||
//! @deprecated Use SetLocalScale()
|
||||
//! Scales the entity along the world's axes. The origin of the axes is the entity's position in the world.
|
||||
//! @param scale A three-dimensional vector that represents the multipliers with which to scale the entity in world space.
|
||||
virtual void SetScale([[maybe_unused]] const AZ::Vector3& scale) {}
|
||||
|
||||
//! @deprecated Use SetLocalScaleX()
|
||||
//! Scales the entity along the world's X axis. The origin of the axis is the entity's position in the world.
|
||||
//! @param scaleX The multiplier by which to scale the entity along the X axis in world space.
|
||||
virtual void SetScaleX([[maybe_unused]] float scaleX) {}
|
||||
|
||||
//! @deprecated Use SetLocalScaleY()
|
||||
//! Scales the entity along the world's Y axis. The origin of the axis is the entity's position in the world.
|
||||
//! @param scaleY The multiplier by which to scale the entity along the Y axis in world space.
|
||||
virtual void SetScaleY([[maybe_unused]] float scaleY) {}
|
||||
|
||||
//! @deprecated Use SetLocalScaleZ()
|
||||
//! Scales the entity along the world's Z axis. The origin of the axis is the entity's position in the world.
|
||||
//! @param scaleZ The multiplier by which to scale the entity along the Z axis in world space.
|
||||
virtual void SetScaleZ([[maybe_unused]] float scaleZ) {}
|
||||
|
||||
//! @deprecated Use GetLocalScale()
|
||||
//! Gets the scale of the entity in world space.
|
||||
//! @return A three-dimensional vector that represents the scale of the entity in world space.
|
||||
virtual AZ::Vector3 GetScale() { return AZ::Vector3(FLT_MAX); }
|
||||
|
||||
//! @deprecated Use GetLocalScale()
|
||||
//! Gets the amount by which an entity is scaled along the world's X axis.
|
||||
//! @return The amount by which an entity is scaled along the X axis in world space.
|
||||
virtual float GetScaleX() { return FLT_MAX; }
|
||||
|
||||
//! @deprecated Use GetLocalScale()
|
||||
//! Gets the amount by which an entity is scaled along the world's Y axis.
|
||||
//! @return The amount by which an entity is scaled along the Y axis in world space.
|
||||
virtual float GetScaleY() { return FLT_MAX; }
|
||||
|
||||
//! @deprecated Use GetLocalScale()
|
||||
//! Gets the amount by which an entity is scaled along the world's Z axis.
|
||||
//! @return The amount by which an entity is scaled along the Z axis in world space.
|
||||
virtual float GetScaleZ() { return FLT_MAX; }
|
||||
|
||||
//! Set local scale of the transform.
|
||||
//! @param scale The new scale to set along three local axes.
|
||||
//! @param scale The new scale to set.
|
||||
virtual void SetLocalScale([[maybe_unused]] const AZ::Vector3& scale) {}
|
||||
|
||||
//! Set local scale of the transform on x-axis.
|
||||
//! @param scaleX The new x-axis scale to set.
|
||||
virtual void SetLocalScaleX([[maybe_unused]] float scaleX) {}
|
||||
|
||||
//! Set local scale of the transform on y-axis.
|
||||
//! @param scaleY The new y-axis scale to set.
|
||||
virtual void SetLocalScaleY([[maybe_unused]] float scaleY) {}
|
||||
|
||||
//! Set local scale of the transform on z-axis.
|
||||
//! @param scaleZ The new z-axis scale to set.
|
||||
virtual void SetLocalScaleZ([[maybe_unused]] float scaleZ) {}
|
||||
|
||||
//! Get the scale value on each axis in local space
|
||||
//! @return The scale value of type Vector3 along each axis in local space.
|
||||
//! Get the scale value in local space.
|
||||
//! @return The scale value in local space.
|
||||
virtual AZ::Vector3 GetLocalScale() { return AZ::Vector3(FLT_MAX); }
|
||||
|
||||
//! Get the scale value on each axis in world space.
|
||||
//! Note the transform will be skewed when it is rotated and has a parent transform scaled, in which
|
||||
//! case the returned world-scale from this function will be inaccurate.
|
||||
//! @return The scale value of type Vector3 along each axis in world space.
|
||||
//! Get the scale value in world space.
|
||||
//! @return The scale value in world space.
|
||||
virtual AZ::Vector3 GetWorldScale() { return AZ::Vector3(FLT_MAX); }
|
||||
|
||||
//! Set the uniform scale value in local space.
|
||||
virtual void SetLocalUniformScale([[maybe_unused]] float scale) {}
|
||||
|
||||
//! Get the uniform scale value in local space.
|
||||
//! @return The uniform scale value in local space.
|
||||
virtual float GetLocalUniformScale() { return FLT_MAX; }
|
||||
|
||||
//! Get the uniform scale value in world space.
|
||||
//! @return The uniform scale value in world space.
|
||||
virtual float GetWorldUniformScale() { return FLT_MAX; }
|
||||
//! @}
|
||||
|
||||
//! Transform hierarchy
|
||||
|
||||
@@ -348,13 +348,20 @@ namespace AZ
|
||||
return result.GetW() >= 0.0f ? result : -result;
|
||||
}
|
||||
|
||||
const Quaternion Quaternion::CreateFromEulerAnglesDegrees(Vector3& anglesInDegrees)
|
||||
const Quaternion Quaternion::CreateFromEulerAnglesDegrees(const Vector3& anglesInDegrees)
|
||||
{
|
||||
Quaternion result;
|
||||
result.SetFromEulerDegrees(anglesInDegrees);
|
||||
return result;
|
||||
}
|
||||
|
||||
const Quaternion Quaternion::CreateFromEulerAnglesRadians(const Vector3& anglesInRadians)
|
||||
{
|
||||
Quaternion result;
|
||||
result.SetFromEulerRadians(anglesInRadians);
|
||||
return result;
|
||||
}
|
||||
|
||||
Quaternion Quaternion::Slerp(const Quaternion& dest, float t) const
|
||||
{
|
||||
const float DestDot = Dot(dest);
|
||||
|
||||
@@ -83,8 +83,11 @@ namespace AZ
|
||||
|
||||
static Quaternion CreateShortestArc(const Vector3& v1, const Vector3& v2);
|
||||
|
||||
/// Creates a quaternion using rotation in degrees about the axes. First rotated about the X axis, followed by the Y axis, then the Z axis.
|
||||
static const Quaternion CreateFromEulerAnglesDegrees(Vector3& anglesInDegrees);
|
||||
//! Creates a quaternion using rotation in degrees about the axes. First rotated about the X axis, followed by the Y axis, then the Z axis.
|
||||
static const Quaternion CreateFromEulerAnglesDegrees(const Vector3& anglesInDegrees);
|
||||
|
||||
//! Creates a quaternion using rotation in radians about the axes. First rotated about the X axis, followed by the Y axis, then the Z axis.
|
||||
static const Quaternion CreateFromEulerAnglesRadians(const Vector3& anglesInRadians);
|
||||
|
||||
//! Stores the vector to an array of 4 floats. The floats need only be 4 byte aligned, 16 byte alignment is not required.
|
||||
void StoreToFloat4(float* values) const;
|
||||
|
||||
@@ -86,4 +86,94 @@ namespace AZ
|
||||
Normal,
|
||||
UniformReal
|
||||
};
|
||||
|
||||
//! Halton sequences are deterministic, quasi-random sequences with low discrepancy. They
|
||||
//! are useful for generating evenly distributed points.
|
||||
//! See https://en.wikipedia.org/wiki/Halton_sequence for more information.
|
||||
|
||||
//! Returns a single halton number.
|
||||
//! @param index The index of the number. Indices start at 1. Using index 0 will return 0.
|
||||
//! @param base The numerical base of the halton number.
|
||||
inline float GetHaltonNumber(uint32_t index, uint32_t base)
|
||||
{
|
||||
float fraction = 1.0f;
|
||||
float result = 0.0f;
|
||||
|
||||
while (index > 0)
|
||||
{
|
||||
fraction = fraction / base;
|
||||
result += fraction * (index % base);
|
||||
index = aznumeric_cast<uint32_t>(index / base);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//! A helper class for generating arrays of Halton sequences in n dimensions.
|
||||
//! The class holds the state of which bases to use, the starting offset
|
||||
//! of each dimension and how much to increment between each index for each
|
||||
//! dimension.
|
||||
template <uint8_t Dimensions>
|
||||
class HaltonSequence
|
||||
{
|
||||
public:
|
||||
|
||||
//! Initializes a Halton sequence with some bases. By default there is no
|
||||
//! offset and the index increments by 1 between each number.
|
||||
HaltonSequence(AZStd::array<uint32_t, Dimensions> bases)
|
||||
: m_bases(bases)
|
||||
{
|
||||
m_offsets.fill(1); // Halton sequences start at index 1.
|
||||
m_increments.fill(1); // By default increment by 1 between each number.
|
||||
}
|
||||
|
||||
//! Returns a Halton sequence in an array of N length
|
||||
template<uint32_t N>
|
||||
AZStd::array<AZStd::array<float, Dimensions>, N> GetHaltonSequence()
|
||||
{
|
||||
AZStd::array<AZStd::array<float, Dimensions>, N> result;
|
||||
|
||||
AZStd::array<uint32_t, Dimensions> indices = m_offsets;
|
||||
|
||||
// Generator that returns the Halton number for all bases for a single entry.
|
||||
auto f = [&] ()
|
||||
{
|
||||
AZStd::array<float, Dimensions> item;
|
||||
for (auto d = 0; d < Dimensions; ++d)
|
||||
{
|
||||
item[d] = GetHaltonNumber(indices[d], m_bases[d]);
|
||||
indices[d] += m_increments[d];
|
||||
}
|
||||
return item;
|
||||
};
|
||||
|
||||
AZStd::generate(result.begin(), result.end(), f);
|
||||
return result;
|
||||
}
|
||||
|
||||
//! Sets the offsets per dimension to start generating a sequence from.
|
||||
//! By default, there is no offset (offset of 0 corresponds to starting at index 1)
|
||||
void SetOffsets(AZStd::array<uint32_t, Dimensions> offsets)
|
||||
{
|
||||
m_offsets = offsets;
|
||||
|
||||
// Halton sequences start at index 1, so increment all the indices.
|
||||
AZStd::for_each(m_offsets.begin(), m_offsets.end(), [](uint32_t &n){ n++; });
|
||||
}
|
||||
|
||||
//! Sets the increment between numbers in the halton sequence per dimension
|
||||
//! By default this is 1, meaning that no numbers are skipped. Can be negative
|
||||
//! to generate numbers in reverse order.
|
||||
void SetIncrements(AZStd::array<int32_t, Dimensions> increments)
|
||||
{
|
||||
m_increments = increments;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
AZStd::array<uint32_t, Dimensions> m_bases;
|
||||
AZStd::array<uint32_t, Dimensions> m_offsets;
|
||||
AZStd::array<int32_t, Dimensions> m_increments;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -441,10 +441,10 @@ namespace AZ
|
||||
const Transform& worldFromLocal, const Vector3& src, const Vector3& dir, const Spline& spline)
|
||||
{
|
||||
Transform worldFromLocalNormalized = worldFromLocal;
|
||||
const Vector3 scale = worldFromLocalNormalized.ExtractScale();
|
||||
const float scale = worldFromLocalNormalized.ExtractUniformScale();
|
||||
const Transform localFromWorldNormalized = worldFromLocalNormalized.GetInverse();
|
||||
|
||||
const Vector3 localRayOrigin = localFromWorldNormalized.TransformPoint(src) * scale.GetReciprocal();
|
||||
const Vector3 localRayOrigin = localFromWorldNormalized.TransformPoint(src) / scale;
|
||||
const Vector3 localRayDirection = localFromWorldNormalized.TransformVector(dir);
|
||||
return spline.GetNearestAddressRay(localRayOrigin, localRayDirection);
|
||||
}
|
||||
|
||||
@@ -284,10 +284,15 @@ namespace AZ
|
||||
Method("GetRotation", &Transform::GetRotation)->
|
||||
Method<void (Transform::*)(const Quaternion&)>("SetRotation", &Transform::SetRotation)->
|
||||
Method("GetScale", &Transform::GetScale)->
|
||||
Method<void (Transform::*)(const Vector3&)>("SetScale", &Transform::SetScale)->
|
||||
Method("GetUniformScale", &Transform::GetUniformScale)->
|
||||
Method("SetScale", &Transform::SetScale)->
|
||||
Method("SetUniformScale", &Transform::SetUniformScale)->
|
||||
Method("ExtractScale", &Transform::ExtractScale)->
|
||||
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
|
||||
Method("ExtractUniformScale", &Transform::ExtractUniformScale)->
|
||||
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
|
||||
Method("MultiplyByScale", &Transform::MultiplyByScale)->
|
||||
Method("MultiplyByUniformScale", &Transform::MultiplyByUniformScale)->
|
||||
Method("GetInverse", &Transform::GetInverse)->
|
||||
Method("Invert", &Transform::Invert)->
|
||||
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
|
||||
@@ -306,6 +311,7 @@ namespace AZ
|
||||
Method("CreateFromMatrix3x3", &Transform::CreateFromMatrix3x3)->
|
||||
Method("CreateFromMatrix3x3AndTranslation", &Transform::CreateFromMatrix3x3AndTranslation)->
|
||||
Method("CreateScale", &Transform::CreateScale)->
|
||||
Method("CreateUniformScale", &Transform::CreateUniformScale)->
|
||||
Method("CreateTranslation", &Transform::CreateTranslation)->
|
||||
Method("ConstructFromValuesNumeric", &Internal::ConstructTransformFromValues);
|
||||
}
|
||||
|
||||
@@ -89,8 +89,11 @@ namespace AZ
|
||||
|
||||
static Transform CreateFromMatrix3x4(const Matrix3x4& value);
|
||||
|
||||
//! Sets the matrix to be a scale matrix, translation is set to zero.
|
||||
static Transform CreateScale(const Vector3& scale);
|
||||
//! Sets the transform to apply scale only, no rotation or translation.
|
||||
static Transform CreateScale(const AZ::Vector3& scale);
|
||||
|
||||
//! Sets the transform to apply (uniform) scale only, no rotation or translation.
|
||||
static Transform CreateUniformScale(const float scale);
|
||||
|
||||
//! Sets the matrix to be a translation matrix, rotation part is set to identity.
|
||||
static Transform CreateTranslation(const Vector3& translation);
|
||||
@@ -119,13 +122,19 @@ namespace AZ
|
||||
const Quaternion& GetRotation() const;
|
||||
void SetRotation(const Quaternion& rotation);
|
||||
|
||||
const Vector3& GetScale() const;
|
||||
Vector3 GetScale() const;
|
||||
float GetUniformScale() const;
|
||||
void SetScale(const Vector3& v);
|
||||
void SetUniformScale(const float scale);
|
||||
|
||||
//! Sets the transforms scale to a unit value and returns the previous scale value.
|
||||
//! Sets the transform's scale to a unit value and returns the previous scale value.
|
||||
Vector3 ExtractScale();
|
||||
|
||||
void MultiplyByScale(const Vector3& scale);
|
||||
//! Sets the transform's scale to a unit value and returns the previous scale value.
|
||||
float ExtractUniformScale();
|
||||
|
||||
void MultiplyByScale(const AZ::Vector3& scale);
|
||||
void MultiplyByUniformScale(float scale);
|
||||
|
||||
Transform operator*(const Transform& rhs) const;
|
||||
Transform& operator*=(const Transform& rhs);
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Transform Transform::CreateScale(const Vector3& scale)
|
||||
{
|
||||
AZ_WarningOnce("Transform", false, "CreateScale is deprecated, please use CreateUniformScale instead.");
|
||||
Transform result;
|
||||
result.m_rotation = Quaternion::CreateIdentity();
|
||||
result.m_scale = scale;
|
||||
@@ -72,6 +73,15 @@ namespace AZ
|
||||
return result;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Transform Transform::CreateUniformScale(float scale)
|
||||
{
|
||||
Transform result;
|
||||
result.m_rotation = Quaternion::CreateIdentity();
|
||||
result.m_scale = Vector3(scale);
|
||||
result.m_translation = Vector3::CreateZero();
|
||||
return result;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Transform Transform::CreateTranslation(const Vector3& translation)
|
||||
{
|
||||
Transform result;
|
||||
@@ -150,24 +160,50 @@ namespace AZ
|
||||
m_rotation = rotation;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE const Vector3& Transform::GetScale() const
|
||||
AZ_MATH_INLINE Vector3 Transform::GetScale() const
|
||||
{
|
||||
AZ_WarningOnce("Transform", false, "GetScale is deprecated, please use GetUniformScale instead.");
|
||||
return m_scale;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE float Transform::GetUniformScale() const
|
||||
{
|
||||
return m_scale.GetMaxElement();
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE void Transform::SetScale(const Vector3& scale)
|
||||
{
|
||||
AZ_WarningOnce("Transform", false, "SetScale is deprecated, please use SetUniformScale instead.");
|
||||
m_scale = scale;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE void Transform::SetUniformScale(const float scale)
|
||||
{
|
||||
m_scale = Vector3(scale);
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Vector3 Transform::ExtractScale()
|
||||
{
|
||||
AZ_WarningOnce("Transform", false, "ExtractScale is deprecated, please use ExtractUniformScale instead.");
|
||||
const Vector3 scale = m_scale;
|
||||
m_scale = Vector3::CreateOne();
|
||||
return scale;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE float Transform::ExtractUniformScale()
|
||||
{
|
||||
const float scale = m_scale.GetMaxElement();
|
||||
m_scale = Vector3::CreateOne();
|
||||
return scale;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE void Transform::MultiplyByScale(const Vector3& scale)
|
||||
{
|
||||
AZ_WarningOnce("Transform", false, "MultiplyByScale is deprecated, please use MultiplyByUniformScale instead.");
|
||||
m_scale *= scale;
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE void Transform::MultiplyByUniformScale(float scale)
|
||||
{
|
||||
m_scale *= scale;
|
||||
}
|
||||
@@ -233,7 +269,7 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE void Transform::Orthogonalize()
|
||||
{
|
||||
*this = GetOrthogonalized();
|
||||
m_scale = Vector3::CreateOne();
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE bool Transform::IsClose(const Transform& rhs, float tolerance) const
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace AZ
|
||||
{
|
||||
// Scale is transitioning to a single uniform scale value, but since it's still internally represented as a Vector3,
|
||||
// we need to pick one number to use for load/store operations.
|
||||
float scale = transformInstance->GetScale().GetMaxElement();
|
||||
float scale = transformInstance->GetUniformScale();
|
||||
|
||||
JSR::ResultCode loadResult =
|
||||
ContinueLoadingFromJsonObjectField(&scale, azrtti_typeid<decltype(scale)>(), inputValue, ScaleTag, context);
|
||||
@@ -124,8 +124,8 @@ namespace AZ
|
||||
|
||||
// Scale is transitioning to a single uniform scale value, but since it's still internally represented as a Vector3,
|
||||
// we need to pick one number to use for load/store operations.
|
||||
float scale = transformInstance->GetScale().GetMaxElement();
|
||||
float defaultScale = defaultTransformInstance ? defaultTransformInstance->GetScale().GetMaxElement() : 0.0f;
|
||||
float scale = transformInstance->GetUniformScale();
|
||||
float defaultScale = defaultTransformInstance ? defaultTransformInstance->GetUniformScale() : 0.0f;
|
||||
|
||||
JSR::ResultCode storeResult = ContinueStoringToJsonObjectField(
|
||||
outputValue, ScaleTag, &scale, defaultTransformInstance ? &defaultScale : nullptr, azrtti_typeid<decltype(scale)>(),
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a pointer to the beginning of master vector of SmallAllocationGroups.
|
||||
/// Returns a pointer to the beginning of vector of SmallAllocationGroups.
|
||||
SmallAllocationGroup* ArrayHead()
|
||||
{
|
||||
return this - m_index;
|
||||
@@ -169,7 +169,7 @@ namespace AZ
|
||||
return m_marker == MARKER;
|
||||
}
|
||||
|
||||
/// Returns the master index of the SmallAllocationGroup containing this allocation
|
||||
/// Returns the index of the SmallAllocationGroup containing this allocation
|
||||
uint32_t GetSmallAllocationIndex() const
|
||||
{
|
||||
return (uint32_t)(m_data & 0xFFFFFFFF);
|
||||
|
||||
@@ -1020,29 +1020,60 @@ namespace AZ
|
||||
}
|
||||
};
|
||||
|
||||
/// OnDemand reflection for AZStd::set
|
||||
|
||||
template<class t_Key, class t_Hasher, class t_EqualKey, class t_Allocator>
|
||||
class Iterator_VM<AZStd::unordered_set<t_Key, t_Hasher, t_EqualKey, t_Allocator>>
|
||||
{
|
||||
public:
|
||||
using ContainerType = AZStd::unordered_set<t_Key, t_Hasher, t_EqualKey, t_Allocator>;
|
||||
using IteratorType = typename ContainerType::iterator;
|
||||
Iterator_VM(ContainerType& container)
|
||||
: m_iterator(container.begin())
|
||||
, m_end(container.end())
|
||||
{}
|
||||
|
||||
const t_Key& GetKeyUnchecked() const
|
||||
{
|
||||
return *m_iterator;
|
||||
}
|
||||
|
||||
bool IsNotAtEnd() const
|
||||
{
|
||||
return m_iterator != m_end;
|
||||
}
|
||||
|
||||
t_Key& ModValueUnchecked()
|
||||
{
|
||||
return *m_iterator;
|
||||
}
|
||||
|
||||
void Next()
|
||||
{
|
||||
++m_iterator;
|
||||
}
|
||||
|
||||
private:
|
||||
IteratorType m_iterator;
|
||||
IteratorType m_end;
|
||||
};
|
||||
|
||||
/// OnDemand reflection for AZStd::unordered_set
|
||||
template<class Key, class Hasher, class EqualKey, class Allocator>
|
||||
struct OnDemandReflection< AZStd::unordered_set<Key, Hasher, EqualKey, Allocator> >
|
||||
{
|
||||
using ContainerType = AZStd::unordered_set<Key, Hasher, EqualKey, Allocator>;
|
||||
using KeyListType = AZStd::vector<Key, Allocator>;
|
||||
|
||||
static AZ::Outcome<void, void> Erase(ContainerType& thisMap, Key& key)
|
||||
using ValueIteratorType = Iterator_VM<ContainerType>;
|
||||
|
||||
static bool EraseCheck_VM(ContainerType& thisSet, Key& key)
|
||||
{
|
||||
const auto result = thisMap.erase(key);
|
||||
if (result)
|
||||
{
|
||||
return AZ::Success();
|
||||
}
|
||||
else
|
||||
{
|
||||
return AZ::Failure();
|
||||
}
|
||||
return thisSet.erase(key) != 0;
|
||||
}
|
||||
|
||||
static void Insert(ContainerType& thisSet, Key& key)
|
||||
static ContainerType& ErasePost_VM(ContainerType& thisSet, [[maybe_unused]] Key&)
|
||||
{
|
||||
thisSet.insert(key);
|
||||
return thisSet;
|
||||
}
|
||||
|
||||
static KeyListType GetKeys(ContainerType& thisSet)
|
||||
@@ -1055,6 +1086,17 @@ namespace AZ
|
||||
return keys;
|
||||
}
|
||||
|
||||
static ContainerType& Insert(ContainerType& thisSet, Key& key)
|
||||
{
|
||||
thisSet.insert(key);
|
||||
return thisSet;
|
||||
}
|
||||
|
||||
static ValueIteratorType Iterate_VM(ContainerType& thisContainer)
|
||||
{
|
||||
return ValueIteratorType(thisContainer);
|
||||
}
|
||||
|
||||
static void Swap(ContainerType& thisSet, ContainerType& otherSet)
|
||||
{
|
||||
thisSet.swap(otherSet);
|
||||
@@ -1064,33 +1106,68 @@ namespace AZ
|
||||
{
|
||||
if (BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context))
|
||||
{
|
||||
BranchOnResultInfo emptyBranchInfo;
|
||||
emptyBranchInfo.m_returnResultInBranches = true;
|
||||
emptyBranchInfo.m_trueToolTip = "The container is empty";
|
||||
emptyBranchInfo.m_falseToolTip = "The container is not empty";
|
||||
|
||||
auto ContainsTransparent = [](const ContainerType& containerType, typename ContainerType::key_type& key)->bool
|
||||
{
|
||||
return containerType.contains(key);
|
||||
};
|
||||
|
||||
ExplicitOverloadInfo explicitOverloadInfo;
|
||||
behaviorContext->Class<ContainerType>()
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::PrettyName, ScriptCanvasOnDemandReflection::OnDemandPrettyName<ContainerType>::Get(*behaviorContext))
|
||||
->Attribute(AZ::Script::Attributes::ToolTip, ScriptCanvasOnDemandReflection::OnDemandToolTip<ContainerType>::Get(*behaviorContext))
|
||||
->Attribute(AZ::Script::Attributes::Category, ScriptCanvasOnDemandReflection::OnDemandCategoryName<ContainerType>::Get(*behaviorContext))
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::ScriptOwn)
|
||||
->Method("BucketCount", static_cast<typename ContainerType::size_type(ContainerType::*)() const>(&ContainerType::bucket_count))
|
||||
->Method("Erase", &Erase)
|
||||
->Method("Empty", [](ContainerType& thisSet)->bool { return thisSet.empty(); })
|
||||
->Method("Empty", static_cast<bool(ContainerType::*)() const>(&ContainerType::empty), { { { "Container", "The container to check if it is empty", nullptr, {} } } })
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Is Empty", "Containers"))
|
||||
->Attribute(AZ::ScriptCanvasAttributes::BranchOnResult, emptyBranchInfo)
|
||||
->Method("EraseCheck_VM", &EraseCheck_VM)
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Method("Erase", &ErasePost_VM)
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Erase", "Containers"))
|
||||
->Attribute(AZ::ScriptCanvasAttributes::CheckedOperation, CheckedOperationInfo("EraseCheck_VM", {}, "Out", "Key Not Found", true))
|
||||
->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup", "" }, { "ContainerGroup" }))
|
||||
->Method("contains", ContainsTransparent)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Has Key", "Containers"))
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Method("Insert", &Insert)
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Insert", "Containers"))
|
||||
->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup", "", "" }, { "ContainerGroup" }))
|
||||
->Method(k_sizeName, [](ContainerType* thisPtr) { return aznumeric_cast<int>(thisPtr->size()); })
|
||||
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::Length)
|
||||
->Method("GetKeys", &GetKeys)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Method("GetSize", [](ContainerType& thisPtr) { return aznumeric_cast<int>(thisPtr.size()); })
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Get Size", "Containers"))
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Method("Reserve", static_cast<void(ContainerType::*)(typename ContainerType::size_type)>(&ContainerType::reserve))
|
||||
->Method("Swap", &Swap)
|
||||
->Method("Clear", [](ContainerType& thisContainer)->ContainerType& { thisContainer.clear(); return thisContainer; })
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Clear All Elements", "Containers"))
|
||||
->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup" }, { "ContainerGroup" }))
|
||||
->Method(k_iteratorConstructorName, &Iterate_VM)
|
||||
;
|
||||
|
||||
behaviorContext->Class<ValueIteratorType>()
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::ScriptOwn)
|
||||
->Method(k_iteratorGetKeyName, &ValueIteratorType::GetKeyUnchecked)
|
||||
->Method(k_iteratorModValueName, &ValueIteratorType::ModValueUnchecked)
|
||||
->Method(k_iteratorIsNotAtEndName, &ValueIteratorType::IsNotAtEnd)
|
||||
->Method(k_iteratorNextName, &ValueIteratorType::Next)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <>
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace AZ
|
||||
|
||||
if (HasResult() != overload->HasResult())
|
||||
{
|
||||
AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all");
|
||||
AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all: %s", m_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace AZ
|
||||
|
||||
if (!(methodResult->m_typeId == overloadResult->m_typeId && methodResult->m_traits == overloadResult->m_traits))
|
||||
{
|
||||
AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all");
|
||||
AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all: %s", m_name.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -575,7 +575,7 @@ namespace AZ
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("BehaviorContext", false, "safety check declared for method %s but it was not found in the class");
|
||||
AZ_Error("BehaviorContext", false, "Method: %s, declared safety check: %s, but it was not found in class: %s", method.m_name.c_str(), m_name.c_str(), checkedOperationInfo.m_safetyCheckName.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,10 +34,17 @@ namespace BehaviorContextUtilitiesCPP
|
||||
using argument_type = const BehaviorParameter*;
|
||||
using result_type = size_t;
|
||||
result_type operator()(const argument_type& value) const
|
||||
{
|
||||
result_type result = AZStd::hash<Uuid>()(value->m_typeId);
|
||||
AZStd::hash_combine(result, CleanTraits(value->m_traits));
|
||||
return result;
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
result_type result = AZStd::hash<Uuid>()(value->m_typeId);
|
||||
AZStd::hash_combine(result, CleanTraits(value->m_traits));
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -45,7 +52,11 @@ namespace BehaviorContextUtilitiesCPP
|
||||
{
|
||||
bool operator()(const BehaviorParameter* left, const BehaviorParameter* right) const
|
||||
{
|
||||
return left->m_typeId == right->m_typeId && CleanTraits(left->m_traits) == CleanTraits(right->m_traits);
|
||||
return (left == nullptr && right == nullptr)
|
||||
|| (left != nullptr
|
||||
&& right != nullptr
|
||||
&& left->m_typeId == right->m_typeId
|
||||
&& CleanTraits(left->m_traits) == CleanTraits(right->m_traits));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -137,7 +148,7 @@ namespace AZ
|
||||
for (size_t argIndex = 0, argSentinel = overload.GetNumArguments(); argIndex < argSentinel; ++argIndex)
|
||||
{
|
||||
auto overloadedArgIter = variance.m_input.find(argIndex);
|
||||
if (overloadedArgIter != variance.m_input.end())
|
||||
if (overloadedArgIter != variance.m_input.end() && overloadedArgIter->second[overloadIndex])
|
||||
{
|
||||
// if this doesn't work try the type name
|
||||
overloadName += ReplaceCppArtifacts(overloadedArgIter->second[overloadIndex]->m_name);
|
||||
@@ -185,16 +196,24 @@ namespace AZ
|
||||
{
|
||||
auto argument = overloads[overloadIndex].first->GetArgument(0);
|
||||
|
||||
const bool isThisPointer
|
||||
= (argument->m_traits & AZ::BehaviorParameter::Traits::TR_THIS_PTR) != 0
|
||||
|| AZ::FindAttribute(AZ::Script::Attributes::TreatAsMemberFunction, overloads[overloadIndex].first->m_attributes);
|
||||
if (argument)
|
||||
{
|
||||
const bool isThisPointer
|
||||
= (argument->m_traits & AZ::BehaviorParameter::Traits::TR_THIS_PTR) != 0
|
||||
|| AZ::FindAttribute(AZ::Script::Attributes::TreatAsMemberFunction, overloads[overloadIndex].first->m_attributes);
|
||||
|
||||
oneArgIsThisPointer = oneArgIsThisPointer || isThisPointer;
|
||||
oneArgIsThisPointer = oneArgIsThisPointer || isThisPointer;
|
||||
}
|
||||
|
||||
types.insert(argument);
|
||||
stripedArgs.emplace_back(argument);
|
||||
}
|
||||
|
||||
if (types.size() == overloads.size())
|
||||
{
|
||||
variance.m_unambiguousInput.insert(0);
|
||||
}
|
||||
|
||||
if (types.size() > 1 && (onThis == VariantOnThis::Yes || !oneArgIsThisPointer))
|
||||
{
|
||||
variance.m_input.insert(AZStd::make_pair(0, stripedArgs));
|
||||
@@ -210,11 +229,15 @@ namespace AZ
|
||||
for (size_t overloadIndex = 0, overloadSentinel = overloads.size(); overloadIndex < overloadSentinel; ++overloadIndex)
|
||||
{
|
||||
auto argument = overloads[overloadIndex].first->GetArgument(argIndex);
|
||||
|
||||
types.insert(argument);
|
||||
stripedArgs.emplace_back(argument);
|
||||
}
|
||||
|
||||
if (types.size() == overloads.size())
|
||||
{
|
||||
variance.m_unambiguousInput.insert(0);
|
||||
}
|
||||
|
||||
if (types.size() > 1)
|
||||
{
|
||||
variance.m_input.insert(AZStd::make_pair(argIndex, stripedArgs));
|
||||
|
||||
@@ -27,6 +27,8 @@ namespace AZ
|
||||
struct OverloadVariance
|
||||
{
|
||||
AZStd::unordered_map<size_t, AZStd::vector<const BehaviorParameter*>> m_input;
|
||||
// the indices of inputs that make selection of overload unambiguous
|
||||
AZStd::unordered_set<size_t> m_unambiguousInput;
|
||||
AZStd::vector<const BehaviorParameter*> m_output;
|
||||
};
|
||||
|
||||
|
||||
@@ -2048,10 +2048,6 @@ LUA_API const Node* lua_getDummyNode()
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("Script", false, "Index %d is not a function!", functionIndex);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -2078,7 +2074,6 @@ LUA_API const Node* lua_getDummyNode()
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("Script", lua_isnil(m_nativeContext, -1), "Name %s exists but is not a function!", functionName);
|
||||
lua_pop(m_nativeContext, 1);
|
||||
}
|
||||
|
||||
@@ -5888,7 +5883,6 @@ LUA_API const Node* lua_getDummyNode()
|
||||
else
|
||||
{
|
||||
lua_pop(m_impl->m_lua, 1);
|
||||
AZ_Warning("Script", false, "%s is not a function!", functionName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -5906,7 +5900,6 @@ LUA_API const Node* lua_getDummyNode()
|
||||
else
|
||||
{
|
||||
lua_pop(m_impl->m_lua, 1);
|
||||
AZ_Warning("Script", false, "CacheIndex %d is not a function!", cachedIndex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "AzCore/RTTI/TypeInfo.h"
|
||||
#include <AzCore/Math/UuidSerializer.h>
|
||||
#include <AzCore/RTTI/AttributeReader.h>
|
||||
#include <AzCore/Serialization/Json/CastingHelpers.h>
|
||||
@@ -61,6 +62,13 @@ namespace AZ
|
||||
|
||||
if (classData->m_azRtti && classData->m_azRtti->GetGenericTypeId() != typeId)
|
||||
{
|
||||
if (((classData->m_azRtti->GetTypeTraits() & (AZ::TypeTraits::is_signed | AZ::TypeTraits::is_unsigned)) != AZ::TypeTraits{0}) &&
|
||||
context.GetSerializeContext()->GetUnderlyingTypeId(typeId) == classData->m_typeId)
|
||||
{
|
||||
// This value is from an enum, where a field has been reflected using ClassBuilder::Field, but the enum
|
||||
// type itself has not been reflected using EnumBuilder. Treat it as an enum.
|
||||
return LoadEnum(object, *classData, value, context);
|
||||
}
|
||||
serializer = context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId());
|
||||
if (serializer)
|
||||
{
|
||||
@@ -77,21 +85,18 @@ namespace AZ
|
||||
{
|
||||
return LoadEnum(object, *classData, value, context);
|
||||
}
|
||||
else if (classData->m_container)
|
||||
if (classData->m_container)
|
||||
{
|
||||
return context.Report(Tasks::ReadField, Outcomes::Unsupported,
|
||||
"The Json Serializer uses custom serializers to load containers. If this message is encountered "
|
||||
"then a serializer for the target containers is missing, isn't registered or doesn't exist.");
|
||||
}
|
||||
else if (value.IsObject())
|
||||
if (value.IsObject())
|
||||
{
|
||||
return LoadClass(object, *classData, value, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
return context.Report(Tasks::ReadField, Outcomes::Unsupported,
|
||||
AZStd::string::format("Reading into targets of type '%s' is not supported.", classData->m_name));
|
||||
}
|
||||
return context.Report(Tasks::ReadField, Outcomes::Unsupported,
|
||||
AZStd::string::format("Reading into targets of type '%s' is not supported.", classData->m_name));
|
||||
}
|
||||
|
||||
JsonSerializationResult::ResultCode JsonDeserializer::LoadToPointer(void* object, const Uuid& typeId,
|
||||
@@ -233,8 +238,16 @@ namespace AZ
|
||||
AZ::TypeId underlyingTypeId = AZ::TypeId::CreateNull();
|
||||
if (!attributeReader.Read<AZ::TypeId>(underlyingTypeId))
|
||||
{
|
||||
return context.Report(Tasks::RetrieveInfo, Outcomes::Unknown,
|
||||
"Unable to find underlying type of enum in class data.");
|
||||
// for non-reflected enums, the passed-in classData already represents the enum's underlying type
|
||||
if (context.GetSerializeContext()->GetUnderlyingTypeId(classData.m_typeId) == classData.m_typeId)
|
||||
{
|
||||
underlyingTypeId = classData.m_typeId;
|
||||
}
|
||||
else
|
||||
{
|
||||
return context.Report(Tasks::RetrieveInfo, Outcomes::Unknown,
|
||||
"Unable to find underlying type of enum in class data.");
|
||||
}
|
||||
}
|
||||
|
||||
const SerializeContext::ClassData* underlyingClassData = context.GetSerializeContext()->FindClassData(underlyingTypeId);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <cerrno>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/JSON/error/en.h>
|
||||
#include <AzCore/NativeUI//NativeUIRequests.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <AzCore/Serialization/Json/StackedString.h>
|
||||
#include <AzCore/Settings/SettingsRegistryImpl.h>
|
||||
@@ -880,6 +881,13 @@ namespace AZ
|
||||
const Specializations& specializations, const rapidjson::Pointer& historyPointer, AZStd::string_view folderPath)
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
if (&lhs == &rhs)
|
||||
{
|
||||
// Early return to avoid setting the collisionFound reference to true
|
||||
// std::sort is allowed to pass in the same memory address for the left and right elements
|
||||
return false;
|
||||
}
|
||||
|
||||
AZ_Assert(!lhs.m_tags.empty(), "Comparing a settings file without at least a name tag.");
|
||||
AZ_Assert(!rhs.m_tags.empty(), "Comparing a settings file without at least a name tag.");
|
||||
@@ -1054,15 +1062,23 @@ namespace AZ
|
||||
jsonPatch.ParseInsitu<flags>(scratchBuffer.data());
|
||||
if (jsonPatch.HasParseError())
|
||||
{
|
||||
auto nativeUI = AZ::Interface<NativeUI::NativeUIRequests>::Get();
|
||||
if (jsonPatch.GetParseError() == rapidjson::kParseErrorDocumentEmpty)
|
||||
{
|
||||
AZ_Warning("Settings Registry", false, R"(Unable to parse registry file "%s" due to json error "%s" at offset %llu.)",
|
||||
AZ_Warning("Settings Registry", false, R"(Unable to parse registry file "%s" due to json error "%s" at offset %zu.)",
|
||||
path, GetParseError_En(jsonPatch.GetParseError()), jsonPatch.GetErrorOffset());
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Settings Registry", false, R"(Unable to parse registry file "%s" due to json error "%s" at offset %llu.)", path,
|
||||
using ErrorString = AZStd::fixed_string<4096>;
|
||||
auto jsonError = ErrorString::format(R"(Unable to parse registry file "%s" due to json error "%s" at offset %zu.)", path,
|
||||
GetParseError_En(jsonPatch.GetParseError()), jsonPatch.GetErrorOffset());
|
||||
AZ_Error("Settings Registry", false, "%s", jsonError.c_str());
|
||||
|
||||
if (nativeUI)
|
||||
{
|
||||
nativeUI->DisplayOkDialog("Setreg(Patch) Merge Issue", AZStd::string_view(jsonError), false);
|
||||
}
|
||||
}
|
||||
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
|
||||
@@ -1740,7 +1740,10 @@ namespace AZ
|
||||
if (!iter->IsInstantiated())
|
||||
{
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
Data::Asset<SliceAsset> thisAsset = Data::AssetManager::Instance().FindAsset(GetMyAsset()->GetId(), AZ::Data::AssetLoadBehavior::Default);
|
||||
Data::Asset<SliceAsset> thisAsset = GetMyAsset()
|
||||
? Data::Asset<SliceAsset>(Data::AssetManager::Instance().FindAsset(
|
||||
GetMyAsset()->GetId(), AZ::Data::AssetLoadBehavior::Default))
|
||||
: Data::Asset<SliceAsset>();
|
||||
AZ_Warning("Slice", false, "Removing %d instances of slice asset %s from parent asset %s due to failed instantiation. "
|
||||
"Saving parent asset will result in loss of slice data.",
|
||||
iter->GetInstances().size(),
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/std/string/osstring.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
namespace AZ
|
||||
|
||||
@@ -41,10 +41,6 @@ namespace AZ
|
||||
if (const char* homePath = std::getenv("HOME"); homePath != nullptr)
|
||||
{
|
||||
AZ::IO::FixedMaxPath path{homePath};
|
||||
if (!path.empty())
|
||||
{
|
||||
path /= ".o3de";
|
||||
}
|
||||
return path.Native();
|
||||
}
|
||||
return {};
|
||||
|
||||
@@ -39,8 +39,8 @@ namespace AZ
|
||||
// Append .framework to the name of full path
|
||||
// Afterwards use the AZ::IO::Path Append function append the filename as a child
|
||||
// of the framework directory
|
||||
AZ::IO::FixedMaxPathString fileName = fullPath.Filename().Native();
|
||||
fullPath.ReplaceFilename(fileName + ".framework");
|
||||
AZ::IO::FixedMaxPathString fileName{ fullPath.Filename().Native() };
|
||||
fullPath.ReplaceFilename(AZ::IO::PathView(AZStd::string_view(fileName + ".framework")));
|
||||
fullPath /= fileName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ namespace UnitTest
|
||||
ErrorHandler::ErrorHandler(const char* errorPattern)
|
||||
: m_errorCount(0)
|
||||
, m_warningCount(0)
|
||||
, m_expectedErrorCount(0)
|
||||
, m_expectedWarningCount(0)
|
||||
, m_errorPattern(errorPattern)
|
||||
{
|
||||
AZ::Debug::TraceMessageBus::Handler::BusConnect();
|
||||
@@ -51,6 +53,16 @@ namespace UnitTest
|
||||
return m_warningCount;
|
||||
}
|
||||
|
||||
int ErrorHandler::GetExpectedErrorCount() const
|
||||
{
|
||||
return m_expectedErrorCount;
|
||||
}
|
||||
|
||||
int ErrorHandler::GetExpectedWarningCount() const
|
||||
{
|
||||
return m_expectedWarningCount;
|
||||
}
|
||||
|
||||
bool ErrorHandler::SuppressExpectedErrors([[maybe_unused]] const char* window, const char* message)
|
||||
{
|
||||
return AZStd::string(message).find(m_errorPattern) != AZStd::string::npos;
|
||||
@@ -61,7 +73,9 @@ namespace UnitTest
|
||||
[[maybe_unused]] const char* func, const char* message)
|
||||
{
|
||||
m_errorCount++;
|
||||
return SuppressExpectedErrors(window, message);
|
||||
bool suppress = SuppressExpectedErrors(window, message);
|
||||
m_expectedErrorCount += suppress;
|
||||
return suppress;
|
||||
}
|
||||
|
||||
bool ErrorHandler::OnPreWarning(
|
||||
@@ -69,7 +83,9 @@ namespace UnitTest
|
||||
[[maybe_unused]] const char* func, const char* message)
|
||||
{
|
||||
m_warningCount++;
|
||||
return SuppressExpectedErrors(window, message);
|
||||
bool suppress = SuppressExpectedErrors(window, message);
|
||||
m_expectedWarningCount += suppress;
|
||||
return suppress;
|
||||
}
|
||||
|
||||
bool ErrorHandler::OnPrintf(const char* window, const char* message)
|
||||
|
||||
@@ -30,8 +30,14 @@ namespace UnitTest
|
||||
public:
|
||||
explicit ErrorHandler(const char* errorPattern);
|
||||
~ErrorHandler();
|
||||
//! Returns the total number of errors encountered (including those which match the expected pattern).
|
||||
int GetErrorCount() const;
|
||||
//! Returns the total number of warnings encountered (including those which match the expected pattern).
|
||||
int GetWarningCount() const;
|
||||
//! Returns the number of errors encountered which matched the expected pattern.
|
||||
int GetExpectedErrorCount() const;
|
||||
//! Returns the number of warnings encountered which matched the expected pattern.
|
||||
int GetExpectedWarningCount() const;
|
||||
bool SuppressExpectedErrors(const char* window, const char* message);
|
||||
|
||||
// AZ::Debug::TraceMessageBus
|
||||
@@ -44,6 +50,8 @@ namespace UnitTest
|
||||
AZStd::string m_errorPattern;
|
||||
int m_errorCount;
|
||||
int m_warningCount;
|
||||
int m_expectedErrorCount;
|
||||
int m_expectedWarningCount;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -61,8 +61,8 @@ namespace MathTestData
|
||||
};
|
||||
|
||||
static const AZ::Transform NonOrthogonalTransforms[] = {
|
||||
AZ::Transform::CreateScale(AZ::Vector3(2.4f, 0.3f, 1.7f)),
|
||||
AZ::Transform::CreateRotationX(2.2f) * AZ::Transform::CreateScale(AZ::Vector3(0.2f, 0.8f, 1.4f))
|
||||
AZ::Transform::CreateUniformScale(2.4f),
|
||||
AZ::Transform::CreateRotationX(2.2f) * AZ::Transform::CreateUniformScale(0.8f)
|
||||
};
|
||||
|
||||
static const AZ::Transform OrthogonalTransforms[] = {
|
||||
|
||||
@@ -59,11 +59,11 @@ namespace UnitTest
|
||||
TEST(MATH_Obb, TestScaleTransform)
|
||||
{
|
||||
Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(position, rotation, halfLengths);
|
||||
Vector3 scaleFactors = Vector3(1.0f, 2.0f, 3.0f);
|
||||
Transform transform = Transform::CreateScale(scaleFactors);
|
||||
float scale = 3.0f;
|
||||
Transform transform = Transform::CreateUniformScale(scale);
|
||||
obb = transform * obb;
|
||||
EXPECT_THAT(obb.GetPosition(), IsClose(Vector3(1.0f, 4.0f, 9.0f)));
|
||||
EXPECT_THAT(obb.GetHalfLengths(), IsClose(Vector3(0.5f, 1.0f, 1.5f)));
|
||||
EXPECT_THAT(obb.GetPosition(), IsClose(Vector3(3.0f, 6.0f, 9.0f)));
|
||||
EXPECT_THAT(obb.GetHalfLengths(), IsClose(Vector3(1.5f, 1.5f, 1.5f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Obb, TestSetPosition)
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Math/Random.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
using namespace AZ;
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
TEST(MATH_Random, GetHaltonNumber)
|
||||
{
|
||||
EXPECT_FLOAT_EQ(0.5, GetHaltonNumber(1, 2));
|
||||
EXPECT_FLOAT_EQ(898.0f / 2187.0f, GetHaltonNumber(1234, 3));
|
||||
EXPECT_FLOAT_EQ(5981.0f / 15625.0f, GetHaltonNumber(4321, 5));
|
||||
}
|
||||
|
||||
TEST(MATH_Random, HaltonSequence)
|
||||
{
|
||||
HaltonSequence<3> sequence({ 2, 3, 5 });
|
||||
auto regularSequence = sequence.GetHaltonSequence<5>();
|
||||
|
||||
EXPECT_FLOAT_EQ(1.0f / 2.0f, regularSequence[0][0]);
|
||||
EXPECT_FLOAT_EQ(1.0f / 3.0f, regularSequence[0][1]);
|
||||
EXPECT_FLOAT_EQ(1.0f / 5.0f, regularSequence[0][2]);
|
||||
|
||||
EXPECT_FLOAT_EQ(1.0f / 4.0f, regularSequence[1][0]);
|
||||
EXPECT_FLOAT_EQ(2.0f / 3.0f, regularSequence[1][1]);
|
||||
EXPECT_FLOAT_EQ(2.0f / 5.0f, regularSequence[1][2]);
|
||||
|
||||
EXPECT_FLOAT_EQ(3.0f / 4.0f, regularSequence[2][0]);
|
||||
EXPECT_FLOAT_EQ(1.0f / 9.0f, regularSequence[2][1]);
|
||||
EXPECT_FLOAT_EQ(3.0f / 5.0f, regularSequence[2][2]);
|
||||
|
||||
EXPECT_FLOAT_EQ(1.0f / 8.0f, regularSequence[3][0]);
|
||||
EXPECT_FLOAT_EQ(4.0f / 9.0f, regularSequence[3][1]);
|
||||
EXPECT_FLOAT_EQ(4.0f / 5.0f, regularSequence[3][2]);
|
||||
|
||||
EXPECT_FLOAT_EQ(5.0f / 8.0f, regularSequence[4][0]);
|
||||
EXPECT_FLOAT_EQ(7.0f / 9.0f, regularSequence[4][1]);
|
||||
EXPECT_FLOAT_EQ(1.0f / 25.0f, regularSequence[4][2]);
|
||||
|
||||
sequence.SetOffsets({ 1, 2, 3 });
|
||||
auto offsetSequence = sequence.GetHaltonSequence<2>();
|
||||
|
||||
EXPECT_FLOAT_EQ(1.0f / 4.0f, offsetSequence[0][0]);
|
||||
EXPECT_FLOAT_EQ(1.0f / 9.0f, offsetSequence[0][1]);
|
||||
EXPECT_FLOAT_EQ(4.0f / 5.0f, offsetSequence[0][2]);
|
||||
|
||||
EXPECT_FLOAT_EQ(3.0f / 4.0f, offsetSequence[1][0]);
|
||||
EXPECT_FLOAT_EQ(4.0f / 9.0f, offsetSequence[1][1]);
|
||||
EXPECT_FLOAT_EQ(1.0f / 25.0f, offsetSequence[1][2]);
|
||||
|
||||
sequence.SetIncrements({ 1, 2, 3 });
|
||||
auto incrementedSequence = sequence.GetHaltonSequence<2>();
|
||||
|
||||
EXPECT_FLOAT_EQ(1.0f / 4.0f, incrementedSequence[0][0]);
|
||||
EXPECT_FLOAT_EQ(1.0f / 9.0f, incrementedSequence[0][1]);
|
||||
EXPECT_FLOAT_EQ(4.0f / 5.0f, incrementedSequence[0][2]);
|
||||
|
||||
EXPECT_FLOAT_EQ(3.0f / 4.0f, incrementedSequence[1][0]);
|
||||
EXPECT_FLOAT_EQ(7.0f / 9.0f, incrementedSequence[1][1]);
|
||||
EXPECT_FLOAT_EQ(11.0f / 25.0f, incrementedSequence[1][2]);
|
||||
}
|
||||
}
|
||||
@@ -180,13 +180,13 @@ namespace Benchmark
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK_F(BM_MathTransform, CreateScale)(benchmark::State& state)
|
||||
BENCHMARK_F(BM_MathTransform, CreateUniformScale)(benchmark::State& state)
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Transform result = AZ::Transform::CreateScale(testData.v3);
|
||||
AZ::Transform result = AZ::Transform::CreateUniformScale(testData.value[0]);
|
||||
benchmark::DoNotOptimize(result);
|
||||
}
|
||||
}
|
||||
@@ -344,39 +344,39 @@ namespace Benchmark
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK_F(BM_MathTransform, GetScale)(benchmark::State& state)
|
||||
BENCHMARK_F(BM_MathTransform, GetUniformScale)(benchmark::State& state)
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Vector3 result = testData.t1.GetScale();
|
||||
float result = testData.t1.GetUniformScale();
|
||||
benchmark::DoNotOptimize(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK_F(BM_MathTransform, SetScale)(benchmark::State& state)
|
||||
BENCHMARK_F(BM_MathTransform, SetUniformScale)(benchmark::State& state)
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Transform testTransform = testData.t2;
|
||||
testTransform.SetScale(testData.v3);
|
||||
testTransform.SetUniformScale(testData.value[0]);
|
||||
benchmark::DoNotOptimize(testTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK_F(BM_MathTransform, ExtractScale)(benchmark::State& state)
|
||||
BENCHMARK_F(BM_MathTransform, ExtractUniformScale)(benchmark::State& state)
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Transform testTransform = testData.t2;
|
||||
AZ::Vector3 result = testTransform.ExtractScale();
|
||||
float result = testTransform.ExtractUniformScale();
|
||||
benchmark::DoNotOptimize(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,37 +159,14 @@ namespace UnitTest
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MATH_Transform, TransformCreateFromQuaternionFixture, ::testing::ValuesIn(MathTestData::UnitQuaternions));
|
||||
|
||||
using TransformCreateFromMatrix3x3Fixture = ::testing::TestWithParam<AZ::Matrix3x3>;
|
||||
|
||||
TEST_P(TransformCreateFromMatrix3x3Fixture, CreateFromMatrix3x3)
|
||||
TEST(MATH_Transform, CreateUniformScale)
|
||||
{
|
||||
const AZ::Matrix3x3 matrix3x3 = GetParam();
|
||||
const AZ::Transform transform = AZ::Transform::CreateFromMatrix3x3(matrix3x3);
|
||||
EXPECT_THAT(transform.GetTranslation(), IsClose(AZ::Vector3::CreateZero()));
|
||||
const AZ::Vector3 vector(2.3f, -0.6, 1.8f);
|
||||
EXPECT_THAT(transform.TransformPoint(vector), IsClose(matrix3x3 * vector));
|
||||
}
|
||||
|
||||
TEST_P(TransformCreateFromMatrix3x3Fixture, CreateFromMatrix3x3AndTranslation)
|
||||
{
|
||||
const AZ::Matrix3x3 matrix3x3 = GetParam();
|
||||
const AZ::Vector3 translation(-2.6f, 1.7f, 0.8f);
|
||||
const AZ::Transform transform = AZ::Transform::CreateFromMatrix3x3AndTranslation(matrix3x3, translation);
|
||||
EXPECT_THAT(transform.GetTranslation(), IsClose(translation));
|
||||
const AZ::Vector3 vector(2.3f, -0.6, 1.8f);
|
||||
EXPECT_THAT(transform.TransformPoint(vector), IsClose(matrix3x3 * vector + translation));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MATH_Transform, TransformCreateFromMatrix3x3Fixture, ::testing::ValuesIn(MathTestData::Matrix3x3s));
|
||||
|
||||
TEST(MATH_Transform, CreateScale)
|
||||
{
|
||||
const AZ::Vector3 scale(1.7f, 0.3f, 2.4f);
|
||||
const AZ::Transform transform = AZ::Transform::CreateScale(scale);
|
||||
const float scale = 1.7f;
|
||||
const AZ::Transform transform = AZ::Transform::CreateUniformScale(scale);
|
||||
const AZ::Vector3 vector(0.2f, -1.6f, 0.4f);
|
||||
EXPECT_THAT(transform.GetTranslation(), IsClose(AZ::Vector3::CreateZero()));
|
||||
const AZ::Vector3 transformedVector = transform.TransformPoint(vector);
|
||||
const AZ::Vector3 expected(0.34f, -0.48f, 0.96f);
|
||||
const AZ::Vector3 expected(0.34f, -2.72f, 0.68f);
|
||||
EXPECT_THAT(transformedVector, IsClose(expected));
|
||||
}
|
||||
|
||||
@@ -237,10 +214,10 @@ namespace UnitTest
|
||||
TEST(MATH_Transform, MultiplyByTransform)
|
||||
{
|
||||
const AZ::Transform transform1 = AZ::Transform::CreateRotationY(0.3f);
|
||||
const AZ::Transform transform2 = AZ::Transform::CreateScale(AZ::Vector3(1.3f, 1.5f, 0.4f));
|
||||
const AZ::Transform transform2 = AZ::Transform::CreateUniformScale(1.3f);
|
||||
const AZ::Transform transform3 = AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
AZ::Quaternion(0.42f, 0.46f, -0.66f, 0.42f), AZ::Vector3(2.8f, -3.7f, 1.6f));
|
||||
const AZ::Transform transform4 = AZ::Transform::CreateRotationX(-0.7f) * AZ::Transform::CreateScale(AZ::Vector3(0.6f, 1.3f, 0.7f));
|
||||
const AZ::Transform transform4 = AZ::Transform::CreateRotationX(-0.7f) * AZ::Transform::CreateUniformScale(0.6f);
|
||||
AZ::Transform transform5 = transform1;
|
||||
transform5 *= transform4;
|
||||
const AZ::Vector3 vector(1.9f, 2.3f, 0.2f);
|
||||
@@ -254,14 +231,14 @@ namespace UnitTest
|
||||
TEST(MATH_Transform, TranslationCorrectInTransformHierarchy)
|
||||
{
|
||||
AZ::Transform parent = AZ::Transform::CreateRotationZ(AZ::DegToRad(45.0f));
|
||||
parent.SetScale(AZ::Vector3(3.0f, 2.0f, 1.0f));
|
||||
parent.SetUniformScale(3.0f);
|
||||
parent.SetTranslation(AZ::Vector3(0.2f, 0.3f, 0.4f));
|
||||
AZ::Transform child = AZ::Transform::CreateRotationZ(AZ::DegToRad(90.0f));
|
||||
child.SetTranslation(AZ::Vector3(0.5f, 0.6f, 0.7f));
|
||||
const AZ::Transform overallTransform = parent * child;
|
||||
const AZ::Vector3 overallTranslation = overallTransform.GetTranslation();
|
||||
const AZ::Vector3 expectedTranslation(0.412132f, 2.20919f, 1.1f);
|
||||
EXPECT_THAT(overallTranslation, IsClose(AZ::Vector3(0.412132f, 2.20919f, 1.1f)));
|
||||
const AZ::Vector3 expectedTranslation(-0.012132f, 2.633452f, 2.5f);
|
||||
EXPECT_THAT(overallTranslation, IsClose(expectedTranslation));
|
||||
}
|
||||
|
||||
TEST(MATH_Transform, TransformPointVector3)
|
||||
@@ -337,14 +314,14 @@ namespace UnitTest
|
||||
TEST_P(TransformScaleFixture, Scale)
|
||||
{
|
||||
const AZ::Transform orthogonalTransform = GetParam();
|
||||
EXPECT_THAT(orthogonalTransform.GetScale(), IsClose(AZ::Vector3::CreateOne()));
|
||||
EXPECT_NEAR(orthogonalTransform.GetUniformScale(), 1.0f, AZ::Constants::Tolerance);
|
||||
AZ::Transform unscaledTransform = orthogonalTransform;
|
||||
unscaledTransform.ExtractScale();
|
||||
EXPECT_THAT(unscaledTransform.GetScale(), IsClose(AZ::Vector3::CreateOne()));
|
||||
const AZ::Vector3 scale(2.8f, 0.7f, 1.3f);
|
||||
unscaledTransform.ExtractUniformScale();
|
||||
EXPECT_NEAR(unscaledTransform.GetUniformScale(), 1.0f, AZ::Constants::Tolerance);
|
||||
const float scale = 2.8f;
|
||||
AZ::Transform scaledTransform = orthogonalTransform;
|
||||
scaledTransform.MultiplyByScale(scale);
|
||||
EXPECT_THAT(scaledTransform.GetScale(), IsClose(scale));
|
||||
scaledTransform.MultiplyByUniformScale(scale);
|
||||
EXPECT_NEAR(scaledTransform.GetUniformScale(), scale, AZ::Constants::Tolerance);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MATH_Transform, TransformScaleFixture, ::testing::ValuesIn(MathTestData::OrthogonalTransforms));
|
||||
@@ -353,24 +330,11 @@ namespace UnitTest
|
||||
{
|
||||
EXPECT_TRUE(AZ::Transform::CreateIdentity().IsOrthogonal());
|
||||
EXPECT_TRUE(AZ::Transform::CreateRotationZ(0.3f).IsOrthogonal());
|
||||
EXPECT_FALSE(AZ::Transform::CreateScale(AZ::Vector3(0.8f, 0.3f, 1.2f)).IsOrthogonal());
|
||||
EXPECT_FALSE(AZ::Transform::CreateUniformScale(0.8f).IsOrthogonal());
|
||||
EXPECT_TRUE(AZ::Transform::CreateFromQuaternion(AZ::Quaternion(-0.52f, -0.08f, 0.56f, 0.64f)).IsOrthogonal());
|
||||
AZ::Transform transform;
|
||||
transform.SetFromEulerRadians(AZ::Vector3(0.2f, 0.4f, 0.1f));
|
||||
EXPECT_TRUE(transform.IsOrthogonal());
|
||||
|
||||
// want to test each possible way the transform could fail to be orthogonal, which we can do by testing for one
|
||||
// axis, then using a rotation which cycles the axes
|
||||
const AZ::Transform axisCycle = AZ::Transform::CreateFromQuaternion(AZ::Quaternion(0.5f, 0.5f, 0.5f, 0.5f));
|
||||
|
||||
// a transform which is normalized in 2 axes, but not the third
|
||||
AZ::Transform nonOrthogonalTransform1 = AZ::Transform::CreateScale(AZ::Vector3(1.0f, 1.0f, 2.0f));
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
EXPECT_FALSE(nonOrthogonalTransform1.IsOrthogonal());
|
||||
nonOrthogonalTransform1 = axisCycle * nonOrthogonalTransform1;
|
||||
}
|
||||
}
|
||||
|
||||
using TransformSetFromEulerDegreesFixture = ::testing::TestWithParam<AZ::Vector3>;
|
||||
@@ -459,16 +423,17 @@ namespace UnitTest
|
||||
{
|
||||
const char* objectStreamBuffer =
|
||||
R"DELIMITER(<ObjectStream version="3">
|
||||
<Class name="Transform" field="m_data" value="0.79429845 0.8545947 -0.94273965 -0.05367075 0.3899708 0.30828915 1.0097652 -0.31084164 0.56899188 513.7845459 492.5420837 32.0000000" type="{5D9958E9-9F1E-4985-B532-FFFDE75FEDFD}"/>
|
||||
<Class name="Transform" field="m_data" value="0.79429845 0.8545947 -0.94273965 -0.1610121 1.1699124 0.92486745 1.2622065 -0.3885522 0.71123985 513.7845459 492.5420837 32.0000000" type="{5D9958E9-9F1E-4985-B532-FFFDE75FEDFD}"/>
|
||||
</ObjectStream>)DELIMITER";
|
||||
|
||||
AZ::Transform* deserializedTransform = AZ::Utils::LoadObjectFromBuffer<AZ::Transform>(objectStreamBuffer, strlen(objectStreamBuffer) + 1);
|
||||
|
||||
const AZ::Vector3 expectedTranslation(513.7845459f, 492.5420837f, 32.0000000f);
|
||||
const AZ::Vector3 expectedScale(1.5f, 0.5f, 1.2f);
|
||||
const float expectedScale = 1.5f;
|
||||
const AZ::Quaternion expectedRotation(0.2624075f, 0.4405251f, 0.2029076f, 0.8342113f);
|
||||
const AZ::Transform expectedTransform =
|
||||
AZ::Transform::CreateFromQuaternionAndTranslation(expectedRotation, expectedTranslation) * AZ::Transform::CreateScale(expectedScale);
|
||||
AZ::Transform::CreateFromQuaternionAndTranslation(expectedRotation, expectedTranslation) *
|
||||
AZ::Transform::CreateUniformScale(expectedScale);
|
||||
|
||||
EXPECT_TRUE(deserializedTransform->IsClose(expectedTransform));
|
||||
azfree(deserializedTransform);
|
||||
|
||||
@@ -1275,10 +1275,10 @@ namespace UnitTest
|
||||
script->Execute("AZTestAssert(t1:TransformVector(Vector3(1, 0, 0)):IsClose(Vector3(1, 0, 0)))");
|
||||
script->Execute("AZTestAssert(t1:TransformVector(Vector3(0, 1, 0)):IsClose(Vector3(0, 0.866, 0.5)))");
|
||||
script->Execute("AZTestAssert(t1:TransformVector(Vector3(0, 0, 1)):IsClose(Vector3(0, -0.5, 0.866)))");
|
||||
script->Execute("t1 = Transform.CreateScale(Vector3(1, 2, 3))");
|
||||
script->Execute("AZTestAssert(t1:TransformVector(Vector3(1, 0, 0)):IsClose(Vector3(1, 0, 0)))");
|
||||
script->Execute("t1 = Transform.CreateUniformScale(2)");
|
||||
script->Execute("AZTestAssert(t1:TransformVector(Vector3(1, 0, 0)):IsClose(Vector3(2, 0, 0)))");
|
||||
script->Execute("AZTestAssert(t1:TransformVector(Vector3(0, 1, 0)):IsClose(Vector3(0, 2, 0)))");
|
||||
script->Execute("AZTestAssert(t1:TransformVector(Vector3(0, 0, 1)):IsClose(Vector3(0, 0, 3)))");
|
||||
script->Execute("AZTestAssert(t1:TransformVector(Vector3(0, 0, 1)):IsClose(Vector3(0, 0, 2)))");
|
||||
script->Execute("t1 = Transform.CreateTranslation(Vector3(1, 2, 3))");
|
||||
script->Execute("AZTestAssert(t1:TransformVector(Vector3(1, 0, 0)):IsClose(Vector3(1, 0, 0)))");
|
||||
script->Execute("AZTestAssert(t1:TransformVector(Vector3(0, 1, 0)):IsClose(Vector3(0, 1, 0)))");
|
||||
@@ -1341,19 +1341,19 @@ namespace UnitTest
|
||||
script->Execute("AZTestAssert(t3:GetTranslation():IsClose(Vector3(-5.90, 25.415, 19.645), 0.001))");
|
||||
|
||||
////test inverse, should handle non-orthogonal matrices
|
||||
script->Execute("t1 = Transform.CreateRotationX(1) * Transform.CreateScale(Vector3(1, 2, 3))");
|
||||
script->Execute("t1 = Transform.CreateRotationX(1) * Transform.CreateUniformScale(2)");
|
||||
script->Execute("AZTestAssert((t1*t1:GetInverse()):IsClose(Transform.CreateIdentity()))");
|
||||
|
||||
////scale access
|
||||
script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(40)) * Transform.CreateScale(Vector3(2, 3, 4))");
|
||||
script->Execute("AZTestAssert(t1:GetScale():IsClose(Vector3(2, 3, 4)))");
|
||||
script->Execute("AZTestAssert(t1:ExtractScale():IsClose(Vector3(2, 3, 4)))");
|
||||
script->Execute("AZTestAssert(t1:GetScale():IsClose(Vector3.CreateOne()))");
|
||||
script->Execute("t1:MultiplyByScale(Vector3(3, 4, 5))");
|
||||
script->Execute("AZTestAssert(t1:GetScale():IsClose(Vector3(3, 4, 5)))");
|
||||
script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(40)) * Transform.CreateUniformScale(3)");
|
||||
script->Execute("AZTestAssertFloatClose(t1:GetUniformScale(), 3)");
|
||||
script->Execute("AZTestAssertFloatClose(t1:ExtractUniformScale(), 3)");
|
||||
script->Execute("AZTestAssertFloatClose(t1:GetUniformScale(), 1)");
|
||||
script->Execute("t1:MultiplyByUniformScale(2)");
|
||||
script->Execute("AZTestAssertFloatClose(t1:GetUniformScale(), 2)");
|
||||
|
||||
////orthogonalize
|
||||
script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(30)) * Transform.CreateScale(Vector3(2, 3, 4))");
|
||||
script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(30)) * Transform.CreateUniformScale(3)");
|
||||
script->Execute("t1:SetTranslation(Vector3(1,2,3))");
|
||||
script->Execute("t2 = t1:GetOrthogonalized()");
|
||||
script->Execute("AZTestAssertFloatClose(t2:GetBasisX():GetLength(), 1)");
|
||||
@@ -1372,7 +1372,7 @@ namespace UnitTest
|
||||
script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(30))");
|
||||
script->Execute("t1:SetTranslation(Vector3(1, 2, 3))");
|
||||
script->Execute("AZTestAssert(t1:IsOrthogonal(0.05))");
|
||||
script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(30)) * Transform.CreateScale(Vector3(2, 3, 4))");
|
||||
script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(30)) * Transform.CreateUniformScale(2)");
|
||||
script->Execute("AZTestAssert( not t1:IsOrthogonal(0.05))");
|
||||
|
||||
////IsClose
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace JsonSerializationTests
|
||||
{
|
||||
using JsonSerializationTestCases = ::testing::Types<
|
||||
// Structures
|
||||
SimpleClass, SimpleInheritence, MultipleInheritence, SimpleNested, SimpleEnumWrapper,
|
||||
SimpleClass, SimpleInheritence, MultipleInheritence, SimpleNested, SimpleEnumWrapper, NonReflectedEnumWrapper,
|
||||
// Pointers
|
||||
SimpleNullPointer, SimpleAssignedPointer, ComplexAssignedPointer, ComplexNullInheritedPointer,
|
||||
ComplexAssignedDifferentInheritedPointer, ComplexAssignedSameInheritedPointer,
|
||||
|
||||
@@ -373,6 +373,57 @@ namespace JsonSerializationTests
|
||||
return MakeInstanceWithoutDefaults(AZStd::move(instance), json);
|
||||
}
|
||||
|
||||
// NonReflectedEnumWrapper
|
||||
bool NonReflectedEnumWrapper::Equals(const NonReflectedEnumWrapper& rhs, bool fullReflection) const
|
||||
{
|
||||
return !fullReflection || (m_enumClass == rhs.m_enumClass && m_rawEnum== rhs.m_rawEnum);
|
||||
}
|
||||
|
||||
void NonReflectedEnumWrapper::Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context, bool fullReflection)
|
||||
{
|
||||
if (fullReflection)
|
||||
{
|
||||
// Note that the enums are not reflected using context->Enum<>
|
||||
|
||||
context->Class<NonReflectedEnumWrapper>()
|
||||
->Field("enumClass", &NonReflectedEnumWrapper::m_enumClass)
|
||||
->Field("rawEnum", &NonReflectedEnumWrapper::m_rawEnum);
|
||||
}
|
||||
}
|
||||
|
||||
InstanceWithSomeDefaults<NonReflectedEnumWrapper> NonReflectedEnumWrapper::GetInstanceWithSomeDefaults()
|
||||
{
|
||||
auto instance = AZStd::make_unique<NonReflectedEnumWrapper>();
|
||||
instance->m_enumClass = NonReflectedEnumWrapper::SimpleEnumClass::Option2;
|
||||
|
||||
const char* strippedDefaults = R"(
|
||||
{
|
||||
"enumClass": 2
|
||||
})";
|
||||
const char* keptDefaults = R"(
|
||||
{
|
||||
"enumClass": 2,
|
||||
"rawEnum": 0
|
||||
})";
|
||||
|
||||
return MakeInstanceWithSomeDefaults(AZStd::move(instance),
|
||||
strippedDefaults, keptDefaults);
|
||||
}
|
||||
|
||||
InstanceWithoutDefaults<NonReflectedEnumWrapper> NonReflectedEnumWrapper::GetInstanceWithoutDefaults()
|
||||
{
|
||||
auto instance = AZStd::make_unique<NonReflectedEnumWrapper>();
|
||||
instance->m_enumClass = NonReflectedEnumWrapper::SimpleEnumClass::Option2;
|
||||
instance->m_rawEnum = NonReflectedEnumWrapper::SimpleRawEnum::RawOption1;
|
||||
|
||||
const char* json = R"(
|
||||
{
|
||||
"enumClass": 2,
|
||||
"rawEnum": 1
|
||||
})";
|
||||
return MakeInstanceWithoutDefaults(AZStd::move(instance), json);
|
||||
}
|
||||
|
||||
// TemplatedClass<int>
|
||||
|
||||
bool TemplatedClass<int>::Equals(const TemplatedClass<int>& rhs, bool fullReflection) const
|
||||
|
||||
@@ -134,6 +134,35 @@ namespace JsonSerializationTests
|
||||
SimpleRawEnum m_rawEnum{};
|
||||
};
|
||||
|
||||
struct NonReflectedEnumWrapper
|
||||
{
|
||||
enum class SimpleEnumClass
|
||||
{
|
||||
Option1 = 1,
|
||||
Option2,
|
||||
};
|
||||
enum SimpleRawEnum
|
||||
{
|
||||
RawOption1 = 1,
|
||||
RawOption2,
|
||||
};
|
||||
AZ_CLASS_ALLOCATOR(NonReflectedEnumWrapper, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(NonReflectedEnumWrapper, "{A80D5B6B-2FD1-46E9-A7A9-44C5E2650526}");
|
||||
|
||||
static constexpr bool SupportsPartialDefaults = true;
|
||||
|
||||
NonReflectedEnumWrapper() = default;
|
||||
virtual ~NonReflectedEnumWrapper() = default;
|
||||
|
||||
bool Equals(const NonReflectedEnumWrapper& rhs, bool fullReflection) const;
|
||||
static void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context, bool fullReflection);
|
||||
static InstanceWithSomeDefaults<NonReflectedEnumWrapper> GetInstanceWithSomeDefaults();
|
||||
static InstanceWithoutDefaults<NonReflectedEnumWrapper> GetInstanceWithoutDefaults();
|
||||
|
||||
SimpleEnumClass m_enumClass{};
|
||||
SimpleRawEnum m_rawEnum{};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct TemplatedClass
|
||||
{
|
||||
@@ -158,5 +187,7 @@ namespace AZ
|
||||
{
|
||||
AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::SimpleEnumWrapper::SimpleEnumClass, "{AF6F1964-5B20-4689-BF23-F36B9C9AAE6A}");
|
||||
AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::SimpleEnumWrapper::SimpleRawEnum, "{EB24207F-B48F-4D8B-940D-3CD06A371739}");
|
||||
AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::NonReflectedEnumWrapper::SimpleEnumClass, "{E80E4A41-B29E-4B7C-B630-3B599172C837}");
|
||||
AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::NonReflectedEnumWrapper::SimpleRawEnum, "{C42AF28D-4F84-4540-972A-5B6EEFAB13FF}");
|
||||
AZ_TYPE_INFO_TEMPLATE(JsonSerializationTests::TemplatedClass, "{CA4ADF74-66E7-4D16-B4AC-F71278C60EC7}", AZ_TYPE_INFO_TYPENAME);
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ namespace JsonSerializationTests
|
||||
TEST_F(JsonTransformSerializerTests, Load_FullySetTransform_ReturnsSuccessWithOnlyScale)
|
||||
{
|
||||
AZ::Transform testTransform = AZ::Transform::CreateIdentity();
|
||||
AZ::Transform expectedTransform = AZ::Transform::CreateScale(AZ::Vector3(5.5f));
|
||||
AZ::Transform expectedTransform = AZ::Transform::CreateUniformScale(5.5f);
|
||||
|
||||
rapidjson::Document json;
|
||||
json.Parse(R"({ "Scale" : 5.5 })");
|
||||
|
||||
@@ -152,6 +152,7 @@ set(FILES
|
||||
Math/PlaneTests.cpp
|
||||
Math/QuaternionPerformanceTests.cpp
|
||||
Math/QuaternionTests.cpp
|
||||
Math/RandomTests.cpp
|
||||
Math/ShapeIntersectionPerformanceTests.cpp
|
||||
Math/ShapeIntersectionTests.cpp
|
||||
Math/SfmtTests.cpp
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace AZ::IO
|
||||
// If used, the source path will be treated as the destination path
|
||||
// and no transformations will be done. Pass this flag when the path is to be the actual
|
||||
// path on the disk/in the packs and doesn't need adjustment (or after it has come through adjustments already)
|
||||
// if this is set, AdjustFileName will not map the input path into the master folder (Ex: Shaders will not be converted to Game\Shaders)
|
||||
// if this is set, AdjustFileName will not map the input path into the folder (Ex: Shaders will not be converted to Game\Shaders)
|
||||
FLAGS_PATH_REAL = 1 << 16,
|
||||
|
||||
// AdjustFileName will always copy the file path to the destination path:
|
||||
@@ -318,7 +318,6 @@ namespace AZ::IO
|
||||
virtual ArchiveFileIterator FindFirst(AZStd::string_view pDir, uint32_t nFlags = 0, bool bAllowUseFileSystem = false) = 0;
|
||||
virtual ArchiveFileIterator FindNext(AZ::IO::ArchiveFileIterator handle) = 0;
|
||||
virtual bool FindClose(AZ::IO::ArchiveFileIterator handle) = 0;
|
||||
// virtual bool IsOutOfDate(const char * szCompiledName, const char * szMasterFile)=0;
|
||||
//returns file modification time
|
||||
virtual IArchive::FileTime GetModificationTime(AZ::IO::HandleType fileHandle) = 0;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace AZ::IO
|
||||
enum EPakFlags
|
||||
{
|
||||
// support for absolute and other complex path specifications -
|
||||
// all paths will be treated relatively to the current directory (normally MasterCD)
|
||||
// all paths will be treated relatively to the current directory
|
||||
FLAGS_ABSOLUTE_PATHS = 1,
|
||||
|
||||
// if this is set, the object will only understand relative to the zip file paths,
|
||||
|
||||
@@ -432,46 +432,26 @@ namespace AzFramework
|
||||
|
||||
void TransformComponent::SetLocalRotation(const AZ::Vector3& eulerRadianAngles)
|
||||
{
|
||||
AZ::Transform newLocalTM = AZ::ConvertEulerRadiansToTransform(eulerRadianAngles);
|
||||
newLocalTM.SetScale(m_localTM.GetScale());
|
||||
newLocalTM.SetTranslation(m_localTM.GetTranslation());
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
newLocalTM.SetRotation(AZ::Quaternion::CreateFromEulerAnglesRadians(eulerRadianAngles));
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalRotationQuaternion(const AZ::Quaternion& quaternion)
|
||||
{
|
||||
AZ::Transform newLocalTM;
|
||||
newLocalTM.SetScale(m_localTM.GetScale());
|
||||
newLocalTM.SetTranslation(m_localTM.GetTranslation());
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
newLocalTM.SetRotation(quaternion);
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
static AZ::Transform RotateAroundLocalHelper(float eulerAngleRadian, const AZ::Transform& localTM, AZ::Vector3 axis)
|
||||
{
|
||||
//get the existing translation and scale
|
||||
AZ::Vector3 translation = localTM.GetTranslation();
|
||||
AZ::Vector3 scale = localTM.GetScale();
|
||||
|
||||
//normalize the axis before creating rotation
|
||||
axis.Normalize();
|
||||
AZ::Quaternion rotate = AZ::Quaternion::CreateFromAxisAngle(axis, eulerAngleRadian);
|
||||
|
||||
//create new rotation transform
|
||||
AZ::Quaternion currentRotate = localTM.GetRotation();
|
||||
AZ::Quaternion newRotate = rotate * currentRotate;
|
||||
newRotate.Normalize();
|
||||
|
||||
//scale
|
||||
AZ::Transform newLocalTM = AZ::Transform::CreateScale(scale);
|
||||
|
||||
//rotate
|
||||
AZ::Transform rotateLocalTM = AZ::Transform::CreateFromQuaternion(newRotate);
|
||||
newLocalTM = rotateLocalTM * newLocalTM;
|
||||
|
||||
//translate
|
||||
newLocalTM.SetTranslation(translation);
|
||||
|
||||
AZ::Transform newLocalTM = localTM;
|
||||
newLocalTM.SetRotation((rotate * localTM.GetRotation()).GetNormalized());
|
||||
return newLocalTM;
|
||||
}
|
||||
|
||||
@@ -512,75 +492,6 @@ namespace AzFramework
|
||||
return m_localTM.GetRotation();
|
||||
}
|
||||
|
||||
void TransformComponent::SetScale(const AZ::Vector3& scale)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "SetScale is deprecated, please use SetLocalScale");
|
||||
|
||||
if (!m_worldTM.GetScale().IsClose(scale))
|
||||
{
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetScale(scale);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
}
|
||||
|
||||
void TransformComponent::SetScaleX(float scaleX)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "SetScaleX is deprecated, please use SetLocalScaleX");
|
||||
|
||||
AZ::Vector3 newScale = m_worldTM.GetScale();
|
||||
newScale.SetX(scaleX);
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetScale(newScale);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetScaleY(float scaleY)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "SetScaleY is deprecated, please use SetLocalScaleY");
|
||||
|
||||
AZ::Vector3 newScale = m_worldTM.GetScale();
|
||||
newScale.SetY(scaleY);
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetScale(newScale);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
void TransformComponent::SetScaleZ(float scaleZ)
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "SetScaleZ is deprecated, please use SetLocalScaleZ");
|
||||
|
||||
AZ::Vector3 newScale = m_worldTM.GetScale();
|
||||
newScale.SetZ(scaleZ);
|
||||
AZ::Transform newWorldTransform = m_worldTM;
|
||||
newWorldTransform.SetScale(newScale);
|
||||
SetWorldTM(newWorldTransform);
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetScale()
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "GetScale is deprecated, please use GetLocalScale");
|
||||
return m_worldTM.GetScale();
|
||||
}
|
||||
|
||||
float TransformComponent::GetScaleX()
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "GetScaleX is deprecated, please use GetLocalScale");
|
||||
return m_worldTM.GetScale().GetX();
|
||||
}
|
||||
|
||||
float TransformComponent::GetScaleY()
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "GetScaleY is deprecated, please use GetLocalScale");
|
||||
return m_worldTM.GetScale().GetY();
|
||||
}
|
||||
|
||||
float TransformComponent::GetScaleZ()
|
||||
{
|
||||
AZ_Warning("TransformComponent", false, "GetScaleZ is deprecated, please use GetLocalScale");
|
||||
return m_worldTM.GetScale().GetZ();
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScale(const AZ::Vector3& scale)
|
||||
{
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
@@ -588,33 +499,6 @@ namespace AzFramework
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScaleX(float scaleX)
|
||||
{
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
AZ::Vector3 newScale = newLocalTM.GetScale();
|
||||
newScale.SetX(scaleX);
|
||||
newLocalTM.SetScale(newScale);
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScaleY(float scaleY)
|
||||
{
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
AZ::Vector3 newScale = newLocalTM.GetScale();
|
||||
newScale.SetY(scaleY);
|
||||
newLocalTM.SetScale(newScale);
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalScaleZ(float scaleZ)
|
||||
{
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
AZ::Vector3 newScale = newLocalTM.GetScale();
|
||||
newScale.SetZ(scaleZ);
|
||||
newLocalTM.SetScale(newScale);
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
AZ::Vector3 TransformComponent::GetLocalScale()
|
||||
{
|
||||
return m_localTM.GetScale();
|
||||
@@ -625,6 +509,23 @@ namespace AzFramework
|
||||
return m_worldTM.GetScale();
|
||||
}
|
||||
|
||||
void TransformComponent::SetLocalUniformScale(float scale)
|
||||
{
|
||||
AZ::Transform newLocalTM = m_localTM;
|
||||
newLocalTM.SetUniformScale(scale);
|
||||
SetLocalTM(newLocalTM);
|
||||
}
|
||||
|
||||
float TransformComponent::GetLocalUniformScale()
|
||||
{
|
||||
return m_localTM.GetUniformScale();
|
||||
}
|
||||
|
||||
float TransformComponent::GetWorldUniformScale()
|
||||
{
|
||||
return m_worldTM.GetUniformScale();
|
||||
}
|
||||
|
||||
AZStd::vector<AZ::EntityId> TransformComponent::GetChildren()
|
||||
{
|
||||
AZStd::vector<AZ::EntityId> children;
|
||||
@@ -979,34 +880,7 @@ namespace AzFramework
|
||||
->Event("GetLocalRotationQuaternion", &AZ::TransformBus::Events::GetLocalRotationQuaternion)
|
||||
->Attribute("Rotation", AZ::Edit::Attributes::PropertyRotation)
|
||||
->VirtualProperty("Rotation", "GetLocalRotationQuaternion", "SetLocalRotationQuaternion")
|
||||
->Event("SetScale", &AZ::TransformBus::Events::SetScale)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetScaleX", &AZ::TransformBus::Events::SetScaleX)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetScaleY", &AZ::TransformBus::Events::SetScaleY)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetScaleZ", &AZ::TransformBus::Events::SetScaleZ)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("GetScale", &AZ::TransformBus::Events::GetScale)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("GetScaleX", &AZ::TransformBus::Events::GetScaleX)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("GetScaleY", &AZ::TransformBus::Events::GetScaleY)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("GetScaleZ", &AZ::TransformBus::Events::GetScaleZ)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Event("SetLocalScale", &AZ::TransformBus::Events::SetLocalScale)
|
||||
->Event("SetLocalScaleX", &AZ::TransformBus::Events::SetLocalScaleX)
|
||||
->Event("SetLocalScaleY", &AZ::TransformBus::Events::SetLocalScaleY)
|
||||
->Event("SetLocalScaleZ", &AZ::TransformBus::Events::SetLocalScaleZ)
|
||||
->Event("GetLocalScale", &AZ::TransformBus::Events::GetLocalScale)
|
||||
->Attribute("Scale", AZ::Edit::Attributes::PropertyScale)
|
||||
->VirtualProperty("Scale", "GetLocalScale", "SetLocalScale")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user