Removed unused Editor code from EditMode/Geometry/Include/LightmapCompiler
Signed-off-by: Chris Galvan <chgalvan@amazon.com>monroegm-disable-blank-issue-2
parent
89067fe667
commit
233349ffe3
@ -1,138 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "EditorDefs.h"
|
|
||||||
|
|
||||||
#include "DeepSelection.h"
|
|
||||||
|
|
||||||
// Editor
|
|
||||||
#include "Objects/BaseObject.h"
|
|
||||||
|
|
||||||
|
|
||||||
//! Functor for sorting selected objects on deep selection mode.
|
|
||||||
struct NearDistance
|
|
||||||
{
|
|
||||||
NearDistance(){}
|
|
||||||
bool operator()(const CDeepSelection::RayHitObject& lhs, const CDeepSelection::RayHitObject& rhs) const
|
|
||||||
{
|
|
||||||
return lhs.distance < rhs.distance;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
CDeepSelection::CDeepSelection()
|
|
||||||
: m_Mode(DSM_NONE)
|
|
||||||
, m_previousMode(DSM_NONE)
|
|
||||||
, m_CandidateObjectCount(0)
|
|
||||||
, m_CurrentSelectedPos(-1)
|
|
||||||
{
|
|
||||||
m_LastPickPoint = QPoint(-1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
CDeepSelection::~CDeepSelection()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void CDeepSelection::Reset(bool bResetLastPick)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < m_CandidateObjectCount; ++i)
|
|
||||||
{
|
|
||||||
m_RayHitObjects[i].object->ClearFlags(OBJFLAG_NO_HITTEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_CandidateObjectCount = 0;
|
|
||||||
m_CurrentSelectedPos = -1;
|
|
||||||
|
|
||||||
m_RayHitObjects.clear();
|
|
||||||
|
|
||||||
if (bResetLastPick)
|
|
||||||
{
|
|
||||||
m_LastPickPoint = QPoint(-1, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void CDeepSelection::AddObject(float distance, CBaseObject* pObj)
|
|
||||||
{
|
|
||||||
m_RayHitObjects.push_back(RayHitObject(distance, pObj));
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
bool CDeepSelection::OnCycling (const QPoint& pt)
|
|
||||||
{
|
|
||||||
QPoint diff = m_LastPickPoint - pt;
|
|
||||||
LONG epsilon = 2;
|
|
||||||
m_LastPickPoint = pt;
|
|
||||||
|
|
||||||
if (abs(diff.x()) < epsilon && abs(diff.y()) < epsilon)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void CDeepSelection::ExcludeHitTest(int except)
|
|
||||||
{
|
|
||||||
int nExcept = except % m_CandidateObjectCount;
|
|
||||||
|
|
||||||
for (int i = 0; i < m_CandidateObjectCount; ++i)
|
|
||||||
{
|
|
||||||
m_RayHitObjects[i].object->SetFlags(OBJFLAG_NO_HITTEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_RayHitObjects[nExcept].object->ClearFlags(OBJFLAG_NO_HITTEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
int CDeepSelection::CollectCandidate(float fMinDistance, float fRange)
|
|
||||||
{
|
|
||||||
m_CandidateObjectCount = 0;
|
|
||||||
|
|
||||||
if (!m_RayHitObjects.empty())
|
|
||||||
{
|
|
||||||
std::sort(m_RayHitObjects.begin(), m_RayHitObjects.end(), NearDistance());
|
|
||||||
|
|
||||||
for (std::vector<CDeepSelection::RayHitObject>::iterator itr = m_RayHitObjects.begin();
|
|
||||||
itr != m_RayHitObjects.end(); ++itr)
|
|
||||||
{
|
|
||||||
if (itr->distance - fMinDistance < fRange)
|
|
||||||
{
|
|
||||||
++m_CandidateObjectCount;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_CandidateObjectCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
CBaseObject* CDeepSelection::GetCandidateObject(int index)
|
|
||||||
{
|
|
||||||
m_CurrentSelectedPos = index % m_CandidateObjectCount;
|
|
||||||
|
|
||||||
return m_RayHitObjects[m_CurrentSelectedPos].object;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//!
|
|
||||||
void CDeepSelection::SetMode(EDeepSelectionMode mode)
|
|
||||||
{
|
|
||||||
m_previousMode = m_Mode;
|
|
||||||
m_Mode = mode;
|
|
||||||
}
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// Description : Deep Selection Header
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CRYINCLUDE_EDITOR_EDITMODE_DEEPSELECTION_H
|
|
||||||
#define CRYINCLUDE_EDITOR_EDITMODE_DEEPSELECTION_H
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
class CBaseObject;
|
|
||||||
|
|
||||||
//! Deep Selection
|
|
||||||
//! Additional output information of HitContext on using "deep selection mode".
|
|
||||||
//! At the deep selection mode, it supports second selection pass for easy
|
|
||||||
//! selection on crowded area with two different method.
|
|
||||||
//! One is to show pop menu of candidate objects list. Another is the cyclic
|
|
||||||
//! selection on pick clicking.
|
|
||||||
class CDeepSelection
|
|
||||||
: public _i_reference_target_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//! Deep Selection Mode Definition
|
|
||||||
enum EDeepSelectionMode
|
|
||||||
{
|
|
||||||
DSM_NONE = 0, // Not using deep selection.
|
|
||||||
DSM_POP = 1, // Deep selection mode with pop context menu.
|
|
||||||
DSM_CYCLE = 2 // Deep selection mode with cyclic selection on each clinking same point.
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Subclass for container of the selected object with hit distance.
|
|
||||||
struct RayHitObject
|
|
||||||
{
|
|
||||||
RayHitObject(float dist, CBaseObject* pObj)
|
|
||||||
: distance(dist)
|
|
||||||
, object(pObj)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
float distance;
|
|
||||||
CBaseObject* object;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Constructor
|
|
||||||
CDeepSelection();
|
|
||||||
virtual ~CDeepSelection();
|
|
||||||
|
|
||||||
void Reset(bool bResetLastPick = false);
|
|
||||||
void AddObject(float distance, CBaseObject* pObj);
|
|
||||||
//! Check if clicking point is same position with last position,
|
|
||||||
//! to decide whether to continue cycling mode.
|
|
||||||
bool OnCycling (const QPoint& pt);
|
|
||||||
//! All objects in list are excluded for hitting test except one, current selection.
|
|
||||||
void ExcludeHitTest(int except);
|
|
||||||
void SetMode(EDeepSelectionMode mode);
|
|
||||||
inline EDeepSelectionMode GetMode() const { return m_Mode; }
|
|
||||||
inline EDeepSelectionMode GetPreviousMode() const { return m_previousMode; }
|
|
||||||
//! Collect object in the deep selection range. The distance from the minimum
|
|
||||||
//! distance is less than deep selection range.
|
|
||||||
int CollectCandidate(float fMinDistance, float fRange);
|
|
||||||
//! Return the candidate object in index position, then it is to be current
|
|
||||||
//! selection position.
|
|
||||||
CBaseObject* GetCandidateObject(int index);
|
|
||||||
//! Return the current selection position that is update in "GetCandidateObject"
|
|
||||||
//! function call.
|
|
||||||
inline int GetCurrentSelectPos() const { return m_CurrentSelectedPos; }
|
|
||||||
//! Return the number of objects in the deep selection range.
|
|
||||||
inline int GetCandidateObjectCount() const { return m_CandidateObjectCount; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
//! Current mode
|
|
||||||
EDeepSelectionMode m_Mode;
|
|
||||||
EDeepSelectionMode m_previousMode;
|
|
||||||
//! Last picking point to check whether cyclic selection continue.
|
|
||||||
QPoint m_LastPickPoint;
|
|
||||||
//! List of the selected objects with ray hitting
|
|
||||||
std::vector<RayHitObject> m_RayHitObjects;
|
|
||||||
int m_CandidateObjectCount;
|
|
||||||
int m_CurrentSelectedPos;
|
|
||||||
};
|
|
||||||
#endif // CRYINCLUDE_EDITOR_EDITMODE_DEEPSELECTION_H
|
|
||||||
@ -1,587 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "EditorDefs.h"
|
|
||||||
|
|
||||||
#include "TriMesh.h"
|
|
||||||
|
|
||||||
// Editor
|
|
||||||
#include "Util/fastlib.h"
|
|
||||||
#include "Objects/SubObjSelection.h"
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
CTriMesh::CTriMesh()
|
|
||||||
{
|
|
||||||
pFaces = nullptr;
|
|
||||||
pVertices = nullptr;
|
|
||||||
pWSVertices = nullptr;
|
|
||||||
pUV = nullptr;
|
|
||||||
pColors = nullptr;
|
|
||||||
pEdges = nullptr;
|
|
||||||
pWeights = nullptr;
|
|
||||||
|
|
||||||
nFacesCount = 0;
|
|
||||||
nVertCount = 0;
|
|
||||||
nUVCount = 0;
|
|
||||||
nEdgeCount = 0;
|
|
||||||
|
|
||||||
selectionType = SO_ELEM_NONE;
|
|
||||||
|
|
||||||
memset(m_streamSize, 0, sizeof(m_streamSize));
|
|
||||||
memset(m_streamSel, 0, sizeof(m_streamSel));
|
|
||||||
streamSelMask = 0;
|
|
||||||
|
|
||||||
m_streamSel[VERTICES] = &vertSel;
|
|
||||||
m_streamSel[EDGES] = &edgeSel;
|
|
||||||
m_streamSel[FACES] = &faceSel;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
CTriMesh::~CTriMesh()
|
|
||||||
{
|
|
||||||
free(pFaces);
|
|
||||||
free(pEdges);
|
|
||||||
free(pVertices);
|
|
||||||
free(pUV);
|
|
||||||
free(pColors);
|
|
||||||
free(pWSVertices);
|
|
||||||
free(pWeights);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set stream size.
|
|
||||||
void CTriMesh::ReallocStream(int stream, int nNewCount)
|
|
||||||
{
|
|
||||||
assert(stream >= 0 && stream < LAST_STREAM);
|
|
||||||
if (stream < 0 || stream >= LAST_STREAM)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_streamSize[stream] == nNewCount)
|
|
||||||
{
|
|
||||||
return; // Stream already have required size.
|
|
||||||
}
|
|
||||||
void* pStream = nullptr;
|
|
||||||
int nElementSize = 0;
|
|
||||||
GetStreamInfo(stream, pStream, nElementSize);
|
|
||||||
pStream = ReAllocElements(pStream, nNewCount, nElementSize);
|
|
||||||
m_streamSize[stream] = nNewCount;
|
|
||||||
|
|
||||||
switch (stream)
|
|
||||||
{
|
|
||||||
case VERTICES:
|
|
||||||
pVertices = (CTriVertex*)pStream;
|
|
||||||
nVertCount = nNewCount;
|
|
||||||
vertSel.resize(nNewCount);
|
|
||||||
break;
|
|
||||||
case FACES:
|
|
||||||
pFaces = (CTriFace*)pStream;
|
|
||||||
nFacesCount = nNewCount;
|
|
||||||
faceSel.resize(nNewCount);
|
|
||||||
break;
|
|
||||||
case EDGES:
|
|
||||||
pEdges = (CTriEdge*)pStream;
|
|
||||||
nEdgeCount = nNewCount;
|
|
||||||
edgeSel.resize(nNewCount);
|
|
||||||
break;
|
|
||||||
case TEXCOORDS:
|
|
||||||
pUV = (SMeshTexCoord*)pStream;
|
|
||||||
nUVCount = nNewCount;
|
|
||||||
break;
|
|
||||||
case COLORS:
|
|
||||||
pColors = (SMeshColor*)pStream;
|
|
||||||
break;
|
|
||||||
case WEIGHTS:
|
|
||||||
pWeights = (float*)pStream;
|
|
||||||
break;
|
|
||||||
case LINES:
|
|
||||||
pLines = (CTriLine*)pStream;
|
|
||||||
break;
|
|
||||||
case WS_POSITIONS:
|
|
||||||
pWSVertices = (Vec3*)pStream;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0); // unknown stream.
|
|
||||||
}
|
|
||||||
m_streamSize[stream] = nNewCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set stream size.
|
|
||||||
void CTriMesh::GetStreamInfo(int stream, void*& pStream, int& nElementSize) const
|
|
||||||
{
|
|
||||||
assert(stream >= 0 && stream < LAST_STREAM);
|
|
||||||
switch (stream)
|
|
||||||
{
|
|
||||||
case VERTICES:
|
|
||||||
pStream = pVertices;
|
|
||||||
nElementSize = sizeof(CTriVertex);
|
|
||||||
break;
|
|
||||||
case FACES:
|
|
||||||
pStream = pFaces;
|
|
||||||
nElementSize = sizeof(CTriFace);
|
|
||||||
break;
|
|
||||||
case EDGES:
|
|
||||||
pStream = pEdges;
|
|
||||||
nElementSize = sizeof(CTriEdge);
|
|
||||||
break;
|
|
||||||
case TEXCOORDS:
|
|
||||||
pStream = pUV;
|
|
||||||
nElementSize = sizeof(SMeshTexCoord);
|
|
||||||
break;
|
|
||||||
case COLORS:
|
|
||||||
pStream = pColors;
|
|
||||||
nElementSize = sizeof(SMeshColor);
|
|
||||||
break;
|
|
||||||
case WEIGHTS:
|
|
||||||
pStream = pWeights;
|
|
||||||
nElementSize = sizeof(float);
|
|
||||||
break;
|
|
||||||
case LINES:
|
|
||||||
pStream = pLines;
|
|
||||||
nElementSize = sizeof(CTriLine);
|
|
||||||
break;
|
|
||||||
case WS_POSITIONS:
|
|
||||||
pStream = pWSVertices;
|
|
||||||
nElementSize = sizeof(Vec3);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0); // unknown stream.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void* CTriMesh::ReAllocElements(void* old_ptr, int new_elem_num, int size_of_element)
|
|
||||||
{
|
|
||||||
return realloc(old_ptr, new_elem_num * size_of_element);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
inline int FindVertexInHash(const Vec3& vPosToFind, const CTriVertex* pVectors, std::vector<int>& hash, float fEpsilon)
|
|
||||||
{
|
|
||||||
for (uint32 i = 0; i < hash.size(); i++)
|
|
||||||
{
|
|
||||||
const Vec3& v0 = pVectors[hash[i]].pos;
|
|
||||||
const Vec3& v1 = vPosToFind;
|
|
||||||
if (fabsf(v0.y - v1.y) < fEpsilon && fabsf(v0.x - v1.x) < fEpsilon && fabsf(v0.z - v1.z) < fEpsilon)
|
|
||||||
{
|
|
||||||
return hash[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
inline int FindTexCoordInHash(const SMeshTexCoord& coordToFind, const SMeshTexCoord* pCoords, std::vector<int>& hash, float fEpsilon)
|
|
||||||
{
|
|
||||||
for (uint32 i = 0; i < hash.size(); i++)
|
|
||||||
{
|
|
||||||
const SMeshTexCoord& t0 = pCoords[hash[i]];
|
|
||||||
const SMeshTexCoord& t1 = coordToFind;
|
|
||||||
|
|
||||||
if (t0.IsEquivalent(t1, fEpsilon))
|
|
||||||
{
|
|
||||||
return hash[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void CTriMesh::SharePositions()
|
|
||||||
{
|
|
||||||
float fEpsilon = 0.0001f;
|
|
||||||
float fHashScale = 256.0f / MAX(bbox.GetSize().GetLength(), fEpsilon);
|
|
||||||
std::vector<int> arrHashTable[256];
|
|
||||||
|
|
||||||
CTriVertex* pNewVerts = new CTriVertex[GetVertexCount()];
|
|
||||||
SMeshColor* pNewColors = nullptr;
|
|
||||||
if (pColors)
|
|
||||||
{
|
|
||||||
pNewColors = new SMeshColor[GetVertexCount()];
|
|
||||||
}
|
|
||||||
|
|
||||||
int nLastIndex = 0;
|
|
||||||
for (int f = 0; f < GetFacesCount(); f++)
|
|
||||||
{
|
|
||||||
CTriFace& face = pFaces[f];
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
const Vec3& v = pVertices[face.v[i]].pos;
|
|
||||||
uint8 nHash = static_cast<uint8>(RoundFloatToInt((v.x + v.y + v.z) * fHashScale));
|
|
||||||
|
|
||||||
int find = FindVertexInHash(v, pNewVerts, arrHashTable[nHash], fEpsilon);
|
|
||||||
if (find < 0)
|
|
||||||
{
|
|
||||||
pNewVerts[nLastIndex] = pVertices[face.v[i]];
|
|
||||||
if (pColors)
|
|
||||||
{
|
|
||||||
pNewColors[nLastIndex] = pColors[face.v[i]];
|
|
||||||
}
|
|
||||||
face.v[i] = nLastIndex;
|
|
||||||
// Reserve some space already.
|
|
||||||
arrHashTable[nHash].reserve(100);
|
|
||||||
arrHashTable[nHash].push_back(nLastIndex);
|
|
||||||
nLastIndex++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
face.v[i] = find;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetVertexCount(nLastIndex);
|
|
||||||
memcpy(pVertices, pNewVerts, nLastIndex * sizeof(CTriVertex));
|
|
||||||
delete []pNewVerts;
|
|
||||||
|
|
||||||
if (pColors)
|
|
||||||
{
|
|
||||||
SetColorsCount(nLastIndex);
|
|
||||||
memcpy(pColors, pNewColors, nLastIndex * sizeof(SMeshColor));
|
|
||||||
delete []pNewColors;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void CTriMesh::ShareUV()
|
|
||||||
{
|
|
||||||
float fEpsilon = 0.0001f;
|
|
||||||
float fHashScale = 256.0f;
|
|
||||||
std::vector<int> arrHashTable[256];
|
|
||||||
|
|
||||||
SMeshTexCoord* pNewUV = new SMeshTexCoord[GetUVCount()];
|
|
||||||
|
|
||||||
int nLastIndex = 0;
|
|
||||||
for (int f = 0; f < GetFacesCount(); f++)
|
|
||||||
{
|
|
||||||
CTriFace& face = pFaces[f];
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
const Vec2 uv = pUV[face.uv[i]].GetUV();
|
|
||||||
uint8 nHash = static_cast<uint8>(RoundFloatToInt((uv.x + uv.y) * fHashScale));
|
|
||||||
|
|
||||||
int find = FindTexCoordInHash(pUV[face.uv[i]], pNewUV, arrHashTable[nHash], fEpsilon);
|
|
||||||
if (find < 0)
|
|
||||||
{
|
|
||||||
pNewUV[nLastIndex] = pUV[face.uv[i]];
|
|
||||||
face.uv[i] = nLastIndex;
|
|
||||||
arrHashTable[nHash].reserve(100);
|
|
||||||
arrHashTable[nHash].push_back(nLastIndex);
|
|
||||||
nLastIndex++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
face.uv[i] = find;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetUVCount(nLastIndex);
|
|
||||||
memcpy(pUV, pNewUV, nLastIndex * sizeof(SMeshTexCoord));
|
|
||||||
delete []pNewUV;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void CTriMesh::CalcFaceNormals()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < nFacesCount; i++)
|
|
||||||
{
|
|
||||||
CTriFace& face = pFaces[i];
|
|
||||||
Vec3 p1 = pVertices[face.v[0]].pos;
|
|
||||||
Vec3 p2 = pVertices[face.v[1]].pos;
|
|
||||||
Vec3 p3 = pVertices[face.v[2]].pos;
|
|
||||||
face.normal = (p2 - p1).Cross(p3 - p1);
|
|
||||||
face.normal.Normalize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TEX_EPS 0.001f
|
|
||||||
#define VER_EPS 0.001f
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void CTriMesh::CopyStream(CTriMesh& fromMesh, int stream)
|
|
||||||
{
|
|
||||||
void* pTrgStream = nullptr;
|
|
||||||
void* pSrcStream = nullptr;
|
|
||||||
int nElemSize = 0;
|
|
||||||
fromMesh.GetStreamInfo(stream, pSrcStream, nElemSize);
|
|
||||||
if (pSrcStream)
|
|
||||||
{
|
|
||||||
ReallocStream(stream, fromMesh.GetStreamSize(stream));
|
|
||||||
GetStreamInfo(stream, pTrgStream, nElemSize);
|
|
||||||
memcpy(pTrgStream, pSrcStream, nElemSize * fromMesh.GetStreamSize(stream));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void CTriMesh::Copy(CTriMesh& fromMesh, int nCopyFlags)
|
|
||||||
{
|
|
||||||
streamSelMask = fromMesh.streamSelMask;
|
|
||||||
|
|
||||||
if (nCopyFlags & COPY_VERTICES)
|
|
||||||
{
|
|
||||||
CopyStream(fromMesh, VERTICES);
|
|
||||||
}
|
|
||||||
if (nCopyFlags & COPY_FACES)
|
|
||||||
{
|
|
||||||
CopyStream(fromMesh, FACES);
|
|
||||||
}
|
|
||||||
if (nCopyFlags & COPY_EDGES)
|
|
||||||
{
|
|
||||||
CopyStream(fromMesh, EDGES);
|
|
||||||
}
|
|
||||||
if (nCopyFlags & COPY_TEXCOORDS)
|
|
||||||
{
|
|
||||||
CopyStream(fromMesh, TEXCOORDS);
|
|
||||||
}
|
|
||||||
if (nCopyFlags & COPY_COLORS)
|
|
||||||
{
|
|
||||||
CopyStream(fromMesh, COLORS);
|
|
||||||
}
|
|
||||||
if (nCopyFlags & COPY_WEIGHTS)
|
|
||||||
{
|
|
||||||
CopyStream(fromMesh, WEIGHTS);
|
|
||||||
}
|
|
||||||
if (nCopyFlags & COPY_LINES)
|
|
||||||
{
|
|
||||||
CopyStream(fromMesh, LINES);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nCopyFlags & COPY_VERT_SEL)
|
|
||||||
{
|
|
||||||
vertSel = fromMesh.vertSel;
|
|
||||||
}
|
|
||||||
if (nCopyFlags & COPY_EDGE_SEL)
|
|
||||||
{
|
|
||||||
edgeSel = fromMesh.edgeSel;
|
|
||||||
}
|
|
||||||
if (nCopyFlags & COPY_FACE_SEL)
|
|
||||||
{
|
|
||||||
faceSel = fromMesh.faceSel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void CTriMesh::UpdateEdges()
|
|
||||||
{
|
|
||||||
SetEdgeCount(GetFacesCount() * 3);
|
|
||||||
|
|
||||||
std::map<CTriEdge, int> edgemap;
|
|
||||||
|
|
||||||
int nEdges = 0;
|
|
||||||
for (int i = 0; i < GetFacesCount(); i++)
|
|
||||||
{
|
|
||||||
CTriFace& face = pFaces[i];
|
|
||||||
for (int j = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
int v0 = j;
|
|
||||||
int v1 = (j != 2) ? j + 1 : 0;
|
|
||||||
CTriEdge edge;
|
|
||||||
edge.flags = 0;
|
|
||||||
|
|
||||||
// First vertex index must always be smaller.
|
|
||||||
if (face.v[v0] < face.v[v1])
|
|
||||||
{
|
|
||||||
edge.v[0] = face.v[v0];
|
|
||||||
edge.v[1] = face.v[v1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
edge.v[0] = face.v[v1];
|
|
||||||
edge.v[1] = face.v[v0];
|
|
||||||
}
|
|
||||||
edge.face[0] = i;
|
|
||||||
edge.face[1] = -1;
|
|
||||||
int nedge = stl::find_in_map(edgemap, edge, -1);
|
|
||||||
if (nedge >= 0)
|
|
||||||
{
|
|
||||||
// Assign this face as a second member of the edge.
|
|
||||||
if (pEdges[nedge].face[1] < 0)
|
|
||||||
{
|
|
||||||
pEdges[nedge].face[1] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
face.edge[j] = nedge;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
edgemap[edge] = nEdges;
|
|
||||||
pEdges[nEdges] = edge;
|
|
||||||
face.edge[j] = nEdges;
|
|
||||||
nEdges++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetEdgeCount(nEdges);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void CTriMesh::SoftSelection(const SSubObjSelOptions& options)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int nVerts = GetVertexCount();
|
|
||||||
CTriVertex* pVerts = pVertices;
|
|
||||||
|
|
||||||
for (i = 0; i < nVerts; i++)
|
|
||||||
{
|
|
||||||
if (pWeights[i] == 1.0f)
|
|
||||||
{
|
|
||||||
const Vec3& vp = pVerts[i].pos;
|
|
||||||
for (int j = 0; j < nVerts; j++)
|
|
||||||
{
|
|
||||||
if (pWeights[j] != 1.0f)
|
|
||||||
{
|
|
||||||
if (vp.IsEquivalent(pVerts[j].pos, options.fSoftSelFalloff))
|
|
||||||
{
|
|
||||||
float fDist = vp.GetDistance(pVerts[j].pos);
|
|
||||||
if (fDist < options.fSoftSelFalloff)
|
|
||||||
{
|
|
||||||
float fWeight = 1.0f - (fDist / options.fSoftSelFalloff);
|
|
||||||
if (fWeight > pWeights[j])
|
|
||||||
{
|
|
||||||
pWeights[j] = fWeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
bool CTriMesh::UpdateSelection()
|
|
||||||
{
|
|
||||||
bool bAnySelected = false;
|
|
||||||
if (selectionType == SO_ELEM_VERTEX)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < GetVertexCount(); i++)
|
|
||||||
{
|
|
||||||
if (vertSel[i])
|
|
||||||
{
|
|
||||||
bAnySelected = true;
|
|
||||||
pWeights[i] = 1.0f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pWeights[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (selectionType == SO_ELEM_EDGE)
|
|
||||||
{
|
|
||||||
// Clear weights.
|
|
||||||
for (int i = 0; i < GetVertexCount(); i++)
|
|
||||||
{
|
|
||||||
pWeights[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < GetEdgeCount(); i++)
|
|
||||||
{
|
|
||||||
if (edgeSel[i])
|
|
||||||
{
|
|
||||||
bAnySelected = true;
|
|
||||||
CTriEdge& edge = pEdges[i];
|
|
||||||
for (int j = 0; j < 2; j++)
|
|
||||||
{
|
|
||||||
pWeights[edge.v[j]] = 1.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (selectionType == SO_ELEM_FACE)
|
|
||||||
{
|
|
||||||
// Clear weights.
|
|
||||||
for (int i = 0; i < GetVertexCount(); i++)
|
|
||||||
{
|
|
||||||
pWeights[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < GetFacesCount(); i++)
|
|
||||||
{
|
|
||||||
if (faceSel[i])
|
|
||||||
{
|
|
||||||
bAnySelected = true;
|
|
||||||
CTriFace& face = pFaces[i];
|
|
||||||
for (int j = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
pWeights[face.v[j]] = 1.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bAnySelected;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
bool CTriMesh::ClearSelection()
|
|
||||||
{
|
|
||||||
bool bWasSelected = false;
|
|
||||||
// Remove all selections.
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < GetVertexCount(); i++)
|
|
||||||
{
|
|
||||||
pWeights[i] = 0;
|
|
||||||
}
|
|
||||||
streamSelMask = 0;
|
|
||||||
for (int ii = 0; ii < LAST_STREAM; ii++)
|
|
||||||
{
|
|
||||||
if (m_streamSel[ii] && !m_streamSel[ii]->is_zero())
|
|
||||||
{
|
|
||||||
bWasSelected = true;
|
|
||||||
m_streamSel[ii]->clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bWasSelected;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void CTriMesh::GetEdgesByVertex(MeshElementsArray& inVertices, MeshElementsArray& outEdges)
|
|
||||||
{
|
|
||||||
// Brute force algorithm using binary search.
|
|
||||||
// for every edge check if edge vertex is inside inVertices array.
|
|
||||||
std::sort(inVertices.begin(), inVertices.end());
|
|
||||||
for (int i = 0; i < GetEdgeCount(); i++)
|
|
||||||
{
|
|
||||||
if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast<int>(pEdges[i].v[0])) != inVertices.end())
|
|
||||||
{
|
|
||||||
outEdges.push_back(i);
|
|
||||||
}
|
|
||||||
else if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast<int>(pEdges[i].v[1])) != inVertices.end())
|
|
||||||
{
|
|
||||||
outEdges.push_back(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void CTriMesh::GetFacesByVertex(MeshElementsArray& inVertices, MeshElementsArray& outFaces)
|
|
||||||
{
|
|
||||||
// Brute force algorithm using binary search.
|
|
||||||
// for every face check if face vertex is inside inVertices array.
|
|
||||||
std::sort(inVertices.begin(), inVertices.end());
|
|
||||||
for (int i = 0; i < GetFacesCount(); i++)
|
|
||||||
{
|
|
||||||
if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast<int>(pFaces[i].v[0])) != inVertices.end())
|
|
||||||
{
|
|
||||||
outFaces.push_back(i);
|
|
||||||
}
|
|
||||||
else if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast<int>(pFaces[i].v[1])) != inVertices.end())
|
|
||||||
{
|
|
||||||
outFaces.push_back(i);
|
|
||||||
}
|
|
||||||
else if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast<int>(pFaces[i].v[2])) != inVertices.end())
|
|
||||||
{
|
|
||||||
outFaces.push_back(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,238 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CRYINCLUDE_EDITOR_GEOMETRY_TRIMESH_H
|
|
||||||
#define CRYINCLUDE_EDITOR_GEOMETRY_TRIMESH_H
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <IIndexedMesh.h>
|
|
||||||
#include "Util/bitarray.h"
|
|
||||||
|
|
||||||
struct SSubObjSelOptions;
|
|
||||||
|
|
||||||
typedef std::vector<int> MeshElementsArray;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Vertex used in the TriMesh.
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
struct CTriVertex
|
|
||||||
{
|
|
||||||
Vec3 pos;
|
|
||||||
//float weight; // Selection weight in 0-1 range.
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Triangle face used by the Triangle mesh.
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
struct CTriFace
|
|
||||||
{
|
|
||||||
uint32 v[3]; // Indices to vertices array.
|
|
||||||
uint32 uv[3]; // Indices to texture coordinates array.
|
|
||||||
Vec3 n[3]; // Vertex normals at face vertices.
|
|
||||||
Vec3 normal; // Face normal.
|
|
||||||
uint32 edge[3]; // Indices to the face edges.
|
|
||||||
unsigned char MatID; // Index of face sub material.
|
|
||||||
unsigned char flags; // see ETriMeshFlags
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Mesh edge.
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
struct CTriEdge
|
|
||||||
{
|
|
||||||
uint32 v[2]; // Indices to edge vertices.
|
|
||||||
int face[2]; // Indices to edge faces (-1 if no face).
|
|
||||||
uint32 flags; // see ETriMeshFlags
|
|
||||||
|
|
||||||
CTriEdge() {}
|
|
||||||
bool operator==(const CTriEdge& edge) const
|
|
||||||
{
|
|
||||||
if ((v[0] == edge.v[0] && v[1] == edge.v[1]) ||
|
|
||||||
(v[0] == edge.v[1] && v[1] == edge.v[0]))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool operator!=(const CTriEdge& edge) const { return !(*this == edge); }
|
|
||||||
bool operator<(const CTriEdge& edge) const { return (*(uint64*)v < *(uint64*)edge.v); }
|
|
||||||
bool operator>(const CTriEdge& edge) const { return (*(uint64*)v > *(uint64*)edge.v); }
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Mesh line.
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
struct CTriLine
|
|
||||||
{
|
|
||||||
uint32 v[2]; // Indices to edge vertices.
|
|
||||||
|
|
||||||
CTriLine() {}
|
|
||||||
bool operator==(const CTriLine& edge) const
|
|
||||||
{
|
|
||||||
if ((v[0] == edge.v[0] && v[1] == edge.v[1]) ||
|
|
||||||
(v[0] == edge.v[1] && v[1] == edge.v[0]))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool operator!=(const CTriLine& edge) const { return !(*this == edge); }
|
|
||||||
bool operator<(const CTriLine& edge) const { return (*(uint64*)v < *(uint64*)edge.v); }
|
|
||||||
bool operator>(const CTriLine& edge) const { return (*(uint64*)v > *(uint64*)edge.v); }
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
struct CTriMeshPoly
|
|
||||||
{
|
|
||||||
std::vector<uint32> v; // Indices to vertices array.
|
|
||||||
std::vector<uint32> uv; // Indices to texture coordinates array.
|
|
||||||
std::vector<Vec3> n; // Vertex normals at face vertices.
|
|
||||||
Vec3 normal; // Polygon normal.
|
|
||||||
uint32 edge[3]; // Indices to the face edges.
|
|
||||||
unsigned char MatID; // Index of face sub material.
|
|
||||||
unsigned char flags; // optional flags.
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// CTriMesh is used in the Editor as a general purpose editable triangle mesh.
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
class CTriMesh
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum EStream
|
|
||||||
{
|
|
||||||
VERTICES,
|
|
||||||
FACES,
|
|
||||||
EDGES,
|
|
||||||
TEXCOORDS,
|
|
||||||
COLORS,
|
|
||||||
WEIGHTS,
|
|
||||||
LINES,
|
|
||||||
WS_POSITIONS,
|
|
||||||
LAST_STREAM,
|
|
||||||
};
|
|
||||||
enum ECopyFlags
|
|
||||||
{
|
|
||||||
COPY_VERTICES = BIT(1),
|
|
||||||
COPY_FACES = BIT(2),
|
|
||||||
COPY_EDGES = BIT(3),
|
|
||||||
COPY_TEXCOORDS = BIT(4),
|
|
||||||
COPY_COLORS = BIT(5),
|
|
||||||
COPY_VERT_SEL = BIT(6),
|
|
||||||
COPY_EDGE_SEL = BIT(7),
|
|
||||||
COPY_FACE_SEL = BIT(8),
|
|
||||||
COPY_WEIGHTS = BIT(9),
|
|
||||||
COPY_LINES = BIT(10),
|
|
||||||
COPY_ALL = 0xFFFF,
|
|
||||||
};
|
|
||||||
// geometry data
|
|
||||||
CTriFace* pFaces;
|
|
||||||
CTriEdge* pEdges;
|
|
||||||
CTriVertex* pVertices;
|
|
||||||
SMeshTexCoord* pUV;
|
|
||||||
SMeshColor* pColors; // If allocated same size as pVerts array.
|
|
||||||
Vec3* pWSVertices; // World space vertices.
|
|
||||||
float* pWeights;
|
|
||||||
CTriLine* pLines;
|
|
||||||
|
|
||||||
int nFacesCount;
|
|
||||||
int nVertCount;
|
|
||||||
int nUVCount;
|
|
||||||
int nEdgeCount;
|
|
||||||
int nLinesCount;
|
|
||||||
|
|
||||||
AABB bbox;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Selections.
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
CBitArray vertSel;
|
|
||||||
CBitArray edgeSel;
|
|
||||||
CBitArray faceSel;
|
|
||||||
// Every bit of the selection mask correspond to a stream, if bit is set this stream have some elements selected
|
|
||||||
int streamSelMask;
|
|
||||||
|
|
||||||
// Selection element type.
|
|
||||||
// see ESubObjElementType
|
|
||||||
int selectionType;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Vertices of the front facing triangles.
|
|
||||||
CBitArray frontFacingVerts;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Functions.
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
CTriMesh();
|
|
||||||
~CTriMesh();
|
|
||||||
|
|
||||||
int GetFacesCount() const { return nFacesCount; }
|
|
||||||
int GetVertexCount() const { return nVertCount; }
|
|
||||||
int GetUVCount() const { return nUVCount; }
|
|
||||||
int GetEdgeCount() const { return nEdgeCount; }
|
|
||||||
int GetLinesCount() const { return nLinesCount; }
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void SetFacesCount(int nNewCount) { ReallocStream(FACES, nNewCount); }
|
|
||||||
void SetVertexCount(int nNewCount)
|
|
||||||
{
|
|
||||||
ReallocStream(VERTICES, nNewCount);
|
|
||||||
if (pColors)
|
|
||||||
{
|
|
||||||
ReallocStream(COLORS, nNewCount);
|
|
||||||
}
|
|
||||||
ReallocStream(WEIGHTS, nNewCount);
|
|
||||||
}
|
|
||||||
void SetColorsCount(int nNewCount) { ReallocStream(COLORS, nNewCount); }
|
|
||||||
void SetUVCount(int nNewCount) { ReallocStream(TEXCOORDS, nNewCount); }
|
|
||||||
void SetEdgeCount(int nNewCount) { ReallocStream(EDGES, nNewCount); }
|
|
||||||
void SetLinesCount(int nNewCount) { ReallocStream(LINES, nNewCount); }
|
|
||||||
|
|
||||||
void ReallocStream(int stream, int nNewCount);
|
|
||||||
void GetStreamInfo(int stream, void*& pStream, int& nElementSize) const;
|
|
||||||
int GetStreamSize(int stream) const { return m_streamSize[stream]; };
|
|
||||||
|
|
||||||
// Calculate per face normal.
|
|
||||||
void CalcFaceNormals();
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Welding functions.
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
void SharePositions();
|
|
||||||
void ShareUV();
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Recreate edges of the mesh.
|
|
||||||
void UpdateEdges();
|
|
||||||
|
|
||||||
void Copy(CTriMesh& fromMesh, int nCopyFlags = COPY_ALL);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Sub-object selection specific methods.
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Return true if something is selected.
|
|
||||||
bool UpdateSelection();
|
|
||||||
// Clear all selections, return true if something was selected.
|
|
||||||
bool ClearSelection();
|
|
||||||
void SoftSelection(const SSubObjSelOptions& options);
|
|
||||||
CBitArray* GetStreamSelection(int nStream) { return m_streamSel[nStream]; };
|
|
||||||
// Returns true if specified stream have any selected elements.
|
|
||||||
bool StreamHaveSelection(int nStream) { return streamSelMask & (1 << nStream); }
|
|
||||||
void GetEdgesByVertex(MeshElementsArray& inVertices, MeshElementsArray& outEdges);
|
|
||||||
void GetFacesByVertex(MeshElementsArray& inVertices, MeshElementsArray& outFaces);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void* ReAllocElements(void* old_ptr, int new_elem_num, int size_of_element);
|
|
||||||
void CopyStream(CTriMesh& fromMesh, int stream);
|
|
||||||
|
|
||||||
// For internal use.
|
|
||||||
int m_streamSize[LAST_STREAM];
|
|
||||||
CBitArray* m_streamSel[LAST_STREAM];
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CRYINCLUDE_EDITOR_GEOMETRY_TRIMESH_H
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IANIMATIONCOMPRESSIONMANAGER_H
|
|
||||||
#define CRYINCLUDE_EDITOR_INCLUDE_IANIMATIONCOMPRESSIONMANAGER_H
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
struct IAnimationCompressionManager
|
|
||||||
{
|
|
||||||
virtual bool IsEnabled() const = 0;
|
|
||||||
virtual void UpdateLocalAnimations() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CRYINCLUDE_EDITOR_INCLUDE_IANIMATIONCOMPRESSIONMANAGER_H
|
|
||||||
@ -1,433 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// Description : Standard interface for asset display in the asset browser,
|
|
||||||
// this header should be used to create plugins.
|
|
||||||
// The method Release of this interface should NOT be called.
|
|
||||||
// Instead, the FreeData from the database (from IAssetItemDatabase) should
|
|
||||||
// be used as it will safely release all the items from the database.
|
|
||||||
// It is still possible to call the release method, but this is not the
|
|
||||||
// recomended method, specially for usage outside of the plugins because there
|
|
||||||
// is no guarantee that a the asset will be properly removed from the database
|
|
||||||
// manager.
|
|
||||||
|
|
||||||
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IASSETITEM_H
|
|
||||||
#define CRYINCLUDE_EDITOR_INCLUDE_IASSETITEM_H
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
struct IAssetItemDatabase;
|
|
||||||
|
|
||||||
namespace AssetViewer
|
|
||||||
{
|
|
||||||
// Used in GetAssetFieldValue for each asset type to check if field name is the right one
|
|
||||||
inline bool IsFieldName(const char* pIncomingFieldName, const char* pFieldName)
|
|
||||||
{
|
|
||||||
return !strncmp(pIncomingFieldName, pFieldName, strlen(pIncomingFieldName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Description:
|
|
||||||
// This interface allows the programmer to extend asset display types visible in the asset browser.
|
|
||||||
struct IAssetItem
|
|
||||||
: public IUnknown
|
|
||||||
{
|
|
||||||
DEFINE_UUID(0x04F20346, 0x2EC3, 0x43f2, 0xBD, 0xA1, 0x2C, 0x0B, 0x97, 0x76, 0xF3, 0x84);
|
|
||||||
|
|
||||||
// The supported asset flags
|
|
||||||
enum EAssetFlags
|
|
||||||
{
|
|
||||||
// asset is visible in the database for filtering and sorting (not asset view control related)
|
|
||||||
eFlag_Visible = BIT(0),
|
|
||||||
// the asset is loaded
|
|
||||||
eFlag_Loaded = BIT(1),
|
|
||||||
// the asset is loaded
|
|
||||||
eFlag_Cached = BIT(2),
|
|
||||||
// the asset is selected in a selection set
|
|
||||||
eFlag_Selected = BIT(3),
|
|
||||||
// this asset is invalid, no thumb is shown/available
|
|
||||||
eFlag_Invalid = BIT(4),
|
|
||||||
// this asset has some errors/warnings, in the asset browser it will show some blinking/red elements
|
|
||||||
// and the user can check out the errors. Error text will be fetched using GetAssetFieldValue( "errors", &someStringVar )
|
|
||||||
eFlag_HasErrors = BIT(5),
|
|
||||||
// this flag is set when the asset is rendering its contents using GDI, and not the engine's rendering capabilities
|
|
||||||
// (this flags is used as hint for the preview tool, which will use a double-buffer canvas if this flag is set,
|
|
||||||
// and send a memory HDC to the OnBeginPreview method, for drawing of the asset)
|
|
||||||
eFlag_UseGdiRendering = BIT(6),
|
|
||||||
// set if this asset is draggable into the render viewports, and can be created there
|
|
||||||
eFlag_CanBeDraggedInViewports = BIT(7),
|
|
||||||
// set if this asset can be moved after creation, otherwise the asset instance will just be created where user clicked
|
|
||||||
eFlag_CanBeMovedAfterDroppedIntoViewport = BIT(8),
|
|
||||||
// the asset thumbnail image is loaded
|
|
||||||
eFlag_ThumbnailLoaded = BIT(9),
|
|
||||||
// the asset thumbnail image is loaded
|
|
||||||
eFlag_UsedInLevel = BIT(10)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Asset field name and field values map
|
|
||||||
typedef std::map < QString/*fieldName*/, QString/*value*/ > TAssetFieldValuesMap;
|
|
||||||
// Dependency category names and corresponding files map, example: "Textures"=>{ "foam.dds","water.dds","normal.dds" }
|
|
||||||
typedef std::map < QString/*dependencyCategory*/, std::set<QString>/*dependency filenames*/ > TAssetDependenciesMap;
|
|
||||||
|
|
||||||
virtual ~IAssetItem() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Description:
|
|
||||||
// Get the hash number/key used for database thumbnail and info records management
|
|
||||||
virtual uint32 GetHash() const = 0;
|
|
||||||
// Description:
|
|
||||||
// Set the hash number/key used for database thumbnail and info records management
|
|
||||||
virtual void SetHash(uint32 hash) = 0;
|
|
||||||
// Description:
|
|
||||||
// Get the owner database for this asset
|
|
||||||
// Return Value:
|
|
||||||
// The owner database for this asset
|
|
||||||
// See Also:
|
|
||||||
// SetOwnerDatabase()
|
|
||||||
virtual IAssetItemDatabase* GetOwnerDatabase() const = 0;
|
|
||||||
// Description:
|
|
||||||
// Set the owner database for this asset
|
|
||||||
// Arguments:
|
|
||||||
// piOwnerDisplayDatabase - the owner database
|
|
||||||
// See Also:
|
|
||||||
// GetOwnerDatabase()
|
|
||||||
virtual void SetOwnerDatabase(IAssetItemDatabase* pOwnerDisplayDatabase) = 0;
|
|
||||||
// Description:
|
|
||||||
// Get the asset's dependency files / objects
|
|
||||||
// Return Value:
|
|
||||||
// The vector with filenames which this asset is dependent upon, ex.: ["Textures"].(vector of textures)
|
|
||||||
virtual const TAssetDependenciesMap& GetDependencies() const = 0;
|
|
||||||
// Description:
|
|
||||||
// Set the file size of this asset in bytes
|
|
||||||
// Arguments:
|
|
||||||
// aSize - size of the file in bytes
|
|
||||||
// See Also:
|
|
||||||
// GetFileSize()
|
|
||||||
virtual void SetFileSize(quint64 aSize) = 0;
|
|
||||||
// Description:
|
|
||||||
// Get the file size of this asset in bytes
|
|
||||||
// Return Value:
|
|
||||||
// The file size of this asset in bytes
|
|
||||||
// See Also:
|
|
||||||
// SetFileSize()
|
|
||||||
virtual quint64 GetFileSize() const = 0;
|
|
||||||
// Description:
|
|
||||||
// Set asset filename (extension included and no path)
|
|
||||||
// Arguments:
|
|
||||||
// pName - the asset filename (extension included and no path)
|
|
||||||
// See Also:
|
|
||||||
// GetFilename()
|
|
||||||
virtual void SetFilename(const char* pName) = 0;
|
|
||||||
// Description:
|
|
||||||
// Get asset filename (extension included and no path)
|
|
||||||
// Return Value:
|
|
||||||
// The asset filename (extension included and no path)
|
|
||||||
// See Also:
|
|
||||||
// SetFilename()
|
|
||||||
virtual QString GetFilename() const = 0;
|
|
||||||
// Description:
|
|
||||||
// Set the asset's relative path
|
|
||||||
// Arguments:
|
|
||||||
// pName - file's relative path
|
|
||||||
// See Also:
|
|
||||||
// GetRelativePath()
|
|
||||||
virtual void SetRelativePath(const char* pName) = 0;
|
|
||||||
// Description:
|
|
||||||
// Get the asset's relative path
|
|
||||||
// Return Value:
|
|
||||||
// The asset's relative path
|
|
||||||
// See Also:
|
|
||||||
// SetRelativePath()
|
|
||||||
virtual QString GetRelativePath() const = 0;
|
|
||||||
// Description:
|
|
||||||
// Set the file extension ( dot(s) must be included )
|
|
||||||
// Arguments:
|
|
||||||
// pExt - the file's extension
|
|
||||||
// See Also:
|
|
||||||
// GetFileExtension()
|
|
||||||
virtual void SetFileExtension(const char* pExt) = 0;
|
|
||||||
// Description:
|
|
||||||
// Get the file extension ( dot(s) included )
|
|
||||||
// Return Value:
|
|
||||||
// The file extension ( dot(s) included )
|
|
||||||
// See Also:
|
|
||||||
// SetFileExtension()
|
|
||||||
virtual QString GetFileExtension() const = 0;
|
|
||||||
// Description:
|
|
||||||
// Get the asset flags, with values from IAssetItem::EAssetFlags
|
|
||||||
// Return Value:
|
|
||||||
// The asset flags, with values from IAssetItem::EAssetFlags
|
|
||||||
// See Also:
|
|
||||||
// SetFlags(), SetFlag(), IsFlagSet()
|
|
||||||
virtual UINT GetFlags() const = 0;
|
|
||||||
// Description:
|
|
||||||
// Set the asset flags
|
|
||||||
// Arguments:
|
|
||||||
// aFlags - flags, OR-ed values from IAssetItem::EAssetFlags
|
|
||||||
// See Also:
|
|
||||||
// GetFlags(), SetFlag(), IsFlagSet()
|
|
||||||
virtual void SetFlags(UINT aFlags) = 0;
|
|
||||||
// Description:
|
|
||||||
// Set/clear a single flag bit for the asset
|
|
||||||
// Arguments:
|
|
||||||
// aFlag - the flag to set/clear, with values from IAssetItem::EAssetFlags
|
|
||||||
// See Also:
|
|
||||||
// GetFlags(), SetFlags(), IsFlagSet()
|
|
||||||
virtual void SetFlag(EAssetFlags aFlag, bool bSet = true) = 0;
|
|
||||||
// Description:
|
|
||||||
// Check if a specified flag is set
|
|
||||||
// Arguments:
|
|
||||||
// aFlag - the flag to check, with values from IAssetItem::EAssetFlags
|
|
||||||
// Return Value:
|
|
||||||
// True if the flag is set
|
|
||||||
// See Also:
|
|
||||||
// GetFlags(), SetFlags(), SetFlag()
|
|
||||||
virtual bool IsFlagSet(EAssetFlags aFlag) const = 0;
|
|
||||||
// Description:
|
|
||||||
// Set this asset's index; used in sorting, selections, and to know where an asset is in the current list
|
|
||||||
// Arguments:
|
|
||||||
// aIndex - the asset's index
|
|
||||||
// See Also:
|
|
||||||
// GetIndex()
|
|
||||||
virtual void SetIndex(UINT aIndex) = 0;
|
|
||||||
// Description:
|
|
||||||
// Get the asset's index in the current list
|
|
||||||
// Return Value:
|
|
||||||
// The asset's index in the current list
|
|
||||||
// See Also:
|
|
||||||
// SetIndex()
|
|
||||||
virtual UINT GetIndex() const = 0;
|
|
||||||
// Description:
|
|
||||||
// Get the asset's field raw data value into a user location, you must check the field's type ( from asset item's owner database )
|
|
||||||
// before using this function and send the correct pointer to destination according to the type ( int8, float32, string, etc. )
|
|
||||||
// Arguments:
|
|
||||||
// pFieldName - the asset field name to query the value for
|
|
||||||
// pDest - the destination variable address, must be the same type as the field type
|
|
||||||
// Return Value:
|
|
||||||
// True if the asset field name is found and the value is returned correctly
|
|
||||||
// See Also:
|
|
||||||
// SetAssetFieldValue()
|
|
||||||
virtual QVariant GetAssetFieldValue(const char* pFieldName) const = 0;
|
|
||||||
// Description:
|
|
||||||
// Set the asset's field raw data value from a user location, you must check the field's type ( from asset item's owner database )
|
|
||||||
// before using this function and send the correct pointer to source according to the type ( int8, float32, string, etc. )
|
|
||||||
// Arguments:
|
|
||||||
// pFieldName - the asset field name to set the value for
|
|
||||||
// pSrc - the source variable address, must be the same type as the field type
|
|
||||||
// Return Value:
|
|
||||||
// True if the asset field name is found and the value is set correctly
|
|
||||||
// See Also:
|
|
||||||
// GetAssetFieldValue()
|
|
||||||
virtual bool SetAssetFieldValue(const char* pFieldName, void* pSrc) = 0;
|
|
||||||
// Description:
|
|
||||||
// Get the drawing rectangle for the asset's thumb ( absolute viewer canvas location )
|
|
||||||
// Arguments:
|
|
||||||
// rstDrawingRectangle - destination location to set with the asset's thumbnail rectangle location
|
|
||||||
// See Also:
|
|
||||||
// SetDrawingRectangle()
|
|
||||||
virtual void GetDrawingRectangle(QRect& rstDrawingRectangle) const = 0;
|
|
||||||
// Description:
|
|
||||||
// Set the drawing rectangle for the asset's thumb ( absolute viewer canvas location )
|
|
||||||
// Arguments:
|
|
||||||
// crstDrawingRectangle - source to set the asset's thumbnail rectangle
|
|
||||||
// See Also:
|
|
||||||
// GetDrawingRectangle()
|
|
||||||
virtual void SetDrawingRectangle(const QRect& crstDrawingRectangle) = 0;
|
|
||||||
// Description:
|
|
||||||
// Checks if the given 2D point is inside the asset's thumb rectangle
|
|
||||||
// Arguments:
|
|
||||||
// nX - mouse pointer position on X axis, relative to the asset viewer control
|
|
||||||
// nY - mouse pointer position on Y axis, relative to the asset viewer control
|
|
||||||
// Return Value:
|
|
||||||
// True if the given 2D point is inside the asset's thumb rectangle
|
|
||||||
// See Also:
|
|
||||||
// HitTest(CRect)
|
|
||||||
virtual bool HitTest(int nX, int nY) const = 0;
|
|
||||||
// Description:
|
|
||||||
// Checks if the given rectangle intersects the asset thumb's rectangle
|
|
||||||
// Arguments:
|
|
||||||
// nX - mouse pointer position on X axis, relative to the asset viewer control
|
|
||||||
// nY - mouse pointer position on Y axis, relative to the asset viewer control
|
|
||||||
// Return Value:
|
|
||||||
// True if the given rectangle intersects the asset thumb's rectangle
|
|
||||||
// See Also:
|
|
||||||
// HitTest(int nX,int nY)
|
|
||||||
virtual bool HitTest(const QRect& roTestRect) const = 0;
|
|
||||||
// Description:
|
|
||||||
// When user drags this asset item into a viewport, this method is called when the dragging operation ends
|
|
||||||
// and the mouse button is released, for the asset to return an instance of the asset object to be placed in the level
|
|
||||||
// Arguments:
|
|
||||||
// aX - instance's X position component in world coordinates
|
|
||||||
// aY - instance's Y position component in world coordinates
|
|
||||||
// aZ - instance's Z position component in world coordinates
|
|
||||||
// Return Value:
|
|
||||||
// The newly created asset instance (Example: BrushObject*)
|
|
||||||
// See Also:
|
|
||||||
// MoveInstanceInViewport()
|
|
||||||
virtual void* CreateInstanceInViewport(float aX, float aY, float aZ) = 0;
|
|
||||||
// Description:
|
|
||||||
// When the mouse button is released after level object creation, the user now can move the mouse
|
|
||||||
// and move the asset instance in the 3D world
|
|
||||||
// Arguments:
|
|
||||||
// pDraggedObject - the actual entity or brush object (CBaseObject* usually) to be moved around with the mouse
|
|
||||||
// returned by the CreateInstanceInViewport()
|
|
||||||
// aNewX - the new X world coordinates of the asset instance
|
|
||||||
// aNewY - the new Y world coordinates of the asset instance
|
|
||||||
// aNewZ - the new Z world coordinates of the asset instance
|
|
||||||
// Return Value:
|
|
||||||
// True if asset instance was moved properly
|
|
||||||
// See Also:
|
|
||||||
// CreateInstanceInViewport()
|
|
||||||
virtual bool MoveInstanceInViewport(const void* pDraggedObject, float aNewX, float aNewY, float aNewZ) = 0;
|
|
||||||
// Description:
|
|
||||||
// This will be called when the user presses ESCAPE key when dragging the asset in the viewport, you must delete the given object
|
|
||||||
// because the creation was aborted
|
|
||||||
// Arguments:
|
|
||||||
// pDraggedObject - the asset instance to be deleted ( you must cast to the needed type, and delete it properly )
|
|
||||||
// See Also:
|
|
||||||
// CreateInstanceInViewport()
|
|
||||||
virtual void AbortCreateInstanceInViewport(const void* pDraggedObject) = 0;
|
|
||||||
// Description:
|
|
||||||
// This method is used to cache/load asset's data, so it can be previewed/rendered
|
|
||||||
// Return Value:
|
|
||||||
// True if the asset was successfully cached
|
|
||||||
// See Also:
|
|
||||||
// UnCache()
|
|
||||||
virtual bool Cache() = 0;
|
|
||||||
// Description:
|
|
||||||
// This method is used to force cache/load asset's data, so it can be previewed/rendered
|
|
||||||
// Return Value:
|
|
||||||
// True if the asset was successfully forced cached
|
|
||||||
// See Also:
|
|
||||||
// UnCache(), Cache()
|
|
||||||
virtual bool ForceCache() = 0;
|
|
||||||
// Description:
|
|
||||||
// This method is used to load the thumbnail image of the asset
|
|
||||||
// Return Value:
|
|
||||||
// True if thumb loaded ok
|
|
||||||
// See Also:
|
|
||||||
// UnloadThumbnail()
|
|
||||||
virtual bool LoadThumbnail() = 0;
|
|
||||||
// Description:
|
|
||||||
// This method is used to unload the thumbnail image of the asset
|
|
||||||
// See Also:
|
|
||||||
// LoadThumbnail()
|
|
||||||
virtual void UnloadThumbnail() = 0;
|
|
||||||
// Description:
|
|
||||||
// This is called when the asset starts to be previewed in full detail, so here you can load the whole asset, in fine detail
|
|
||||||
// ( textures are fully loaded, models etc. ). It is called once, when the Preview dialog is shown
|
|
||||||
// Arguments:
|
|
||||||
// hPreviewWnd - the window handle of the quick preview dialog
|
|
||||||
// hMemDC - the memory DC used to render assets that can render themselves in the DC, otherwise they will render in the dialog's HWND
|
|
||||||
// See Also:
|
|
||||||
// OnEndPreview(), GetCustomPreviewPanelHeader()
|
|
||||||
virtual void OnBeginPreview(QWidget* hPreviewWnd) = 0;
|
|
||||||
// Description:
|
|
||||||
// Called when the Preview dialog is closed, you may release the detail asset data here
|
|
||||||
// See Also:
|
|
||||||
// OnBeginPreview(), GetCustomPreviewPanelHeader()
|
|
||||||
virtual void OnEndPreview() = 0;
|
|
||||||
// Description:
|
|
||||||
// If the asset has a special preview panel with utility controls, to be placed at the top of the Preview window, it can return an child dialog window
|
|
||||||
// otherwise it can return nullptr, if no panel is available
|
|
||||||
// Arguments:
|
|
||||||
// pParentWnd - a valid CDialog*, or nullptr
|
|
||||||
// Return Value:
|
|
||||||
// A valid child dialog window handle, if this asset wants to have a custom panel in the top side of the Asset Preview window,
|
|
||||||
// otherwise it can return nullptr, if no panel is available
|
|
||||||
// See Also:
|
|
||||||
// OnBeginPreview(), OnEndPreview()
|
|
||||||
virtual QWidget* GetCustomPreviewPanelHeader(QWidget* pParentWnd) = 0;
|
|
||||||
virtual QWidget* GetCustomPreviewPanelFooter(QWidget* pParentWnd) = 0;
|
|
||||||
// Description:
|
|
||||||
// Used when dragging/rotate/zoom a model, or other asset that can support preview
|
|
||||||
// Arguments:
|
|
||||||
// hRenderWindow - the rendering window handle
|
|
||||||
// rstViewport - the viewport rectangle
|
|
||||||
// aMouseX - the render window relative mouse pointer X coordinate
|
|
||||||
// aMouseY - the render window relative mouse pointer Y coordinate
|
|
||||||
// aMouseDeltaX - the X coordinate delta between two mouse movements
|
|
||||||
// aMouseDeltaY - the Y coordinate delta between two mouse movements
|
|
||||||
// aMouseWheelDelta - the mouse wheel scroll delta/step
|
|
||||||
// aKeyFlags - the key flags, see WM_LBUTTONUP
|
|
||||||
// See Also:
|
|
||||||
// OnPreviewRenderKeyEvent()
|
|
||||||
virtual void PreviewRender(
|
|
||||||
QWidget* hRenderWindow,
|
|
||||||
const QRect& rstViewport,
|
|
||||||
int aMouseX = 0, int aMouseY = 0,
|
|
||||||
int aMouseDeltaX = 0, int aMouseDeltaY = 0,
|
|
||||||
int aMouseWheelDelta = 0, UINT aKeyFlags = 0) = 0;
|
|
||||||
// Description:
|
|
||||||
// This is called when the user manipulates the assets in interactive render and a key is pressed ( with down or up state )
|
|
||||||
// Arguments:
|
|
||||||
// bKeyDown - true if this is a WM_KEYDOWN event, else it is a WM_KEYUP event
|
|
||||||
// aChar - the char/key code pressed/released
|
|
||||||
// aKeyFlags - the key flags, compatible with WM_KEYDOWN/UP events
|
|
||||||
// See Also:
|
|
||||||
// InteractiveRender()
|
|
||||||
virtual void OnPreviewRenderKeyEvent(bool bKeyDown, UINT aChar, UINT aKeyFlags) = 0;
|
|
||||||
// Description:
|
|
||||||
// Called when user clicked once on the thumb image
|
|
||||||
// Arguments:
|
|
||||||
// point - mouse coordinates relative to the thumbnail rectangle
|
|
||||||
// aKeyFlags - the key flags, see WM_LBUTTONDOWN
|
|
||||||
// See Also:
|
|
||||||
// OnThumbDblClick()
|
|
||||||
virtual void OnThumbClick(const QPoint& point, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) = 0;
|
|
||||||
// Description:
|
|
||||||
// Called when user double clicked on the thumb image
|
|
||||||
// Arguments:
|
|
||||||
// point - mouse coordinates relative to the thumbnail rectangle
|
|
||||||
// aKeyFlags - the key flags, see WM_LBUTTONDOWN
|
|
||||||
// See Also:
|
|
||||||
// OnThumbClick()
|
|
||||||
//! called when user clicked twice on the thumb image
|
|
||||||
virtual void OnThumbDblClick(const QPoint& point, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) = 0;
|
|
||||||
// Description:
|
|
||||||
// Draw the cached thumb bitmap only, if any, no other kind of rendering
|
|
||||||
// Arguments:
|
|
||||||
// hDC - the destination DC, where to draw the thumb
|
|
||||||
// rRect - the destination rectangle
|
|
||||||
// Return Value:
|
|
||||||
// True if drawing of the thumbnail was done OK
|
|
||||||
// See Also:
|
|
||||||
// Render()
|
|
||||||
virtual bool DrawThumbImage(QPainter* painter, const QRect& rRect) = 0;
|
|
||||||
// Description:
|
|
||||||
// Writes asset info to a XML node.
|
|
||||||
// This is needed to save cached info as a persistent XML file for the next run of the editor.
|
|
||||||
// Arguments:
|
|
||||||
// node - An XML node to contain the info
|
|
||||||
// See Also:
|
|
||||||
// FromXML()
|
|
||||||
virtual void ToXML(XmlNodeRef& node) const = 0;
|
|
||||||
// Description:
|
|
||||||
// Gets asset info from a XML node.
|
|
||||||
// This is needed to get the asset info from previous runs of the editor without re-caching it.
|
|
||||||
// Arguments:
|
|
||||||
// node - An XML node that contains info for this asset
|
|
||||||
// See Also:
|
|
||||||
// ToXML()
|
|
||||||
virtual void FromXML(const XmlNodeRef& node) = 0;
|
|
||||||
|
|
||||||
// From IUnknown
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface([[maybe_unused]] const IID& riid, [[maybe_unused]] void** ppvObject)
|
|
||||||
{
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
};
|
|
||||||
virtual ULONG STDMETHODCALLTYPE AddRef()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
virtual ULONG STDMETHODCALLTYPE Release()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
#endif // CRYINCLUDE_EDITOR_INCLUDE_IASSETITEM_H
|
|
||||||
@ -1,259 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// Description : Standard interface for asset database creators used to
|
|
||||||
// create an asset plugin for the asset browser
|
|
||||||
// The category of the plugin must be Asset Item DB
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IASSETITEMDATABASE_H
|
|
||||||
#define CRYINCLUDE_EDITOR_INCLUDE_IASSETITEMDATABASE_H
|
|
||||||
#pragma once
|
|
||||||
struct IAssetItem;
|
|
||||||
struct IAssetViewer;
|
|
||||||
|
|
||||||
class QString;
|
|
||||||
class QStringList;
|
|
||||||
|
|
||||||
// Description:
|
|
||||||
// This struct keeps the info, filter and sorting settings for an asset field
|
|
||||||
struct SAssetField
|
|
||||||
{
|
|
||||||
// the condition for the current filter on the field
|
|
||||||
enum EAssetFilterCondition
|
|
||||||
{
|
|
||||||
eCondition_Any = 0,
|
|
||||||
// string conditions
|
|
||||||
// this also supports '*' and '?' as wildcards inside text
|
|
||||||
eCondition_Contains,
|
|
||||||
// this filter will search the target for at least one of the words specified
|
|
||||||
// ( ex: filter: "water car moon" , field value : "the_great_moon.dds", this will pass the test
|
|
||||||
// it also supports '*' and '?' as wildcards inside words text
|
|
||||||
eCondition_ContainsOneOfTheWords,
|
|
||||||
eCondition_StartsWith,
|
|
||||||
eCondition_EndsWith,
|
|
||||||
// string & numerical conditions
|
|
||||||
eCondition_Equal,
|
|
||||||
eCondition_Greater,
|
|
||||||
eCondition_Less,
|
|
||||||
eCondition_GreaterOrEqual,
|
|
||||||
eCondition_LessOrEqual,
|
|
||||||
eCondition_Not,
|
|
||||||
eCondition_InsideRange
|
|
||||||
};
|
|
||||||
|
|
||||||
// the asset field type
|
|
||||||
enum EAssetFieldType
|
|
||||||
{
|
|
||||||
eType_None = 0,
|
|
||||||
eType_Bool,
|
|
||||||
eType_Int8,
|
|
||||||
eType_Int16,
|
|
||||||
eType_Int32,
|
|
||||||
eType_Int64,
|
|
||||||
eType_Float,
|
|
||||||
eType_Double,
|
|
||||||
eType_String
|
|
||||||
};
|
|
||||||
|
|
||||||
// used when a field can have different specific values
|
|
||||||
typedef QStringList TFieldEnumValues;
|
|
||||||
|
|
||||||
SAssetField(
|
|
||||||
const char* pFieldName = "",
|
|
||||||
const char* pDisplayName = "Unnamed field",
|
|
||||||
EAssetFieldType aFieldType = eType_None,
|
|
||||||
UINT aColumnWidth = 50,
|
|
||||||
bool bVisibleInUI = true,
|
|
||||||
bool bReadOnly = true)
|
|
||||||
{
|
|
||||||
m_fieldName = pFieldName;
|
|
||||||
m_displayName = pDisplayName;
|
|
||||||
m_fieldType = aFieldType;
|
|
||||||
m_filterCondition = eCondition_Equal;
|
|
||||||
m_bUseEnumValues = false;
|
|
||||||
m_bReadOnly = bReadOnly;
|
|
||||||
m_listColumnWidth = aColumnWidth;
|
|
||||||
m_bFieldVisibleInUI = bVisibleInUI;
|
|
||||||
m_bPostFilter = false;
|
|
||||||
|
|
||||||
SetupEnumValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupEnumValues()
|
|
||||||
{
|
|
||||||
m_bUseEnumValues = true;
|
|
||||||
|
|
||||||
if (m_fieldType == eType_Bool)
|
|
||||||
{
|
|
||||||
m_enumValues.clear();
|
|
||||||
m_enumValues.push_back("Yes");
|
|
||||||
m_enumValues.push_back("No");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// the field's display name, used in UI
|
|
||||||
QString m_displayName,
|
|
||||||
// the field internal name, used in C++ code
|
|
||||||
m_fieldName,
|
|
||||||
// the current filter value, if its empty "" then no filter is applied
|
|
||||||
m_filterValue,
|
|
||||||
// the field's max value, valid when the field's filter condition is eAssertFilterCondition_InsideRange
|
|
||||||
m_maxFilterValue,
|
|
||||||
// the name of the database holding this field, used in Asset Browser preset editor, if its "" then the field
|
|
||||||
// is common to all current databases
|
|
||||||
m_parentDatabaseName;
|
|
||||||
// is this field visible in the UI ?
|
|
||||||
bool m_bFieldVisibleInUI,
|
|
||||||
// if true, then you cannot modify this field of an asset item, only use it
|
|
||||||
m_bReadOnly,
|
|
||||||
// this field filter is applied after the other filters
|
|
||||||
m_bPostFilter;
|
|
||||||
// the field data type
|
|
||||||
EAssetFieldType m_fieldType;
|
|
||||||
// the filter's condition
|
|
||||||
EAssetFilterCondition m_filterCondition;
|
|
||||||
// use the enum list values to choose a value for the field ?
|
|
||||||
bool m_bUseEnumValues;
|
|
||||||
// this map is used when asset field has m_bUseEnumValues on true,
|
|
||||||
// choose a value for the field from this list in the UI
|
|
||||||
TFieldEnumValues m_enumValues;
|
|
||||||
// recommended list column width
|
|
||||||
unsigned int m_listColumnWidth;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SFieldFiltersPreset
|
|
||||||
{
|
|
||||||
QString presetName2;
|
|
||||||
QStringList checkedDatabaseNames;
|
|
||||||
bool bUsedInLevel;
|
|
||||||
std::vector<SAssetField> fields;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Description:
|
|
||||||
// This interface allows the programmer to extend asset display types
|
|
||||||
// visible in the asset browser.
|
|
||||||
struct IAssetItemDatabase
|
|
||||||
: public IUnknown
|
|
||||||
{
|
|
||||||
DEFINE_UUID(0xFB09B039, 0x1D9D, 0x4057, 0xA5, 0xF0, 0xAA, 0x3C, 0x7B, 0x97, 0xAE, 0xA8)
|
|
||||||
|
|
||||||
typedef std::vector<SAssetField> TAssetFields;
|
|
||||||
typedef std::map < QString/*field name*/, SAssetField > TAssetFieldFiltersMap;
|
|
||||||
typedef std::map < QString/*asset filename*/, IAssetItem* > TFilenameAssetMap;
|
|
||||||
typedef AZStd::function<bool(const IAssetItem*)> MetaDataChangeListener;
|
|
||||||
|
|
||||||
// Description:
|
|
||||||
// Refresh the database by scanning the folders/paks for files, does not load the files, only filename and filesize are fetched
|
|
||||||
virtual void Refresh() = 0;
|
|
||||||
// Description:
|
|
||||||
// Fills the asset meta data from the loaded xml meta data DB.
|
|
||||||
// Arguments:
|
|
||||||
// db - the database XML node from where to cache the info
|
|
||||||
virtual void PrecacheFieldsInfoFromFileDB(const XmlNodeRef& db) = 0;
|
|
||||||
// Description:
|
|
||||||
// Return all assets loaded/scanned by this database
|
|
||||||
// Return Value:
|
|
||||||
// The assets map reference (filename-asset)
|
|
||||||
virtual TFilenameAssetMap& GetAssets() = 0;
|
|
||||||
// Description:
|
|
||||||
// Get an asset item by its filename
|
|
||||||
// Return Value:
|
|
||||||
// A single asset from the database given the filename
|
|
||||||
virtual IAssetItem* GetAsset(const char* pAssetFilename) = 0;
|
|
||||||
// Description:
|
|
||||||
// Return the asset fields this database's items support
|
|
||||||
// Return Value:
|
|
||||||
// The asset fields vector reference
|
|
||||||
virtual TAssetFields& GetAssetFields() = 0;
|
|
||||||
// Description:
|
|
||||||
// Return an asset field object pointer by the field internal name
|
|
||||||
// Arguments:
|
|
||||||
// pFieldName - the internal field's name (ex: "filename", "relativepath")
|
|
||||||
// Return Value:
|
|
||||||
// The asset field object pointer
|
|
||||||
virtual SAssetField* GetAssetFieldByName(const char* pFieldName) = 0;
|
|
||||||
// Description:
|
|
||||||
// Get the database name
|
|
||||||
// Return Value:
|
|
||||||
// Returns the database name, ex: "Textures"
|
|
||||||
virtual const char* GetDatabaseName() const = 0;
|
|
||||||
// Description:
|
|
||||||
// Get the database supported file name extension(s)
|
|
||||||
// Return Value:
|
|
||||||
// Returns the supported extensions, separated by comma, ex: "tga,bmp,dds"
|
|
||||||
virtual const char* GetSupportedExtensions() const = 0;
|
|
||||||
// Description:
|
|
||||||
// Free the database internal data structures
|
|
||||||
virtual void FreeData() = 0;
|
|
||||||
// Description:
|
|
||||||
// Apply filters to this database which will set/unset the IAssetItem::eAssetFlag_Visible of each asset, based
|
|
||||||
// on the given field filters
|
|
||||||
// Arguments:
|
|
||||||
// rFieldFilters - a reference to the field filters map (fieldname-field)
|
|
||||||
// See Also:
|
|
||||||
// ClearFilters()
|
|
||||||
virtual void ApplyFilters(const TAssetFieldFiltersMap& rFieldFilters) = 0;
|
|
||||||
// Description:
|
|
||||||
// Clear the current filters, by setting the IAssetItem::eAssetFlag_Visible of each asset to true
|
|
||||||
// See Also:
|
|
||||||
// ApplyFilters()
|
|
||||||
virtual void ClearFilters() = 0;
|
|
||||||
virtual QWidget* CreateDbFilterDialog(QWidget* pParent, IAssetViewer* pViewerCtrl) = 0;
|
|
||||||
virtual void UpdateDbFilterDialogUI(QWidget* pDlg) = 0;
|
|
||||||
virtual void OnAssetBrowserOpen() = 0;
|
|
||||||
virtual void OnAssetBrowserClose() = 0;
|
|
||||||
// Description:
|
|
||||||
// Gets the filename for saving new cached asset info.
|
|
||||||
// Return Value:
|
|
||||||
// A file name to save new transactions to the persistent asset info DB
|
|
||||||
// See Also:
|
|
||||||
// CAssetInfoFileDB, IAssetItem::ToXML(), IAssetItem::FromXML()
|
|
||||||
virtual const char* GetTransactionFilename() const = 0;
|
|
||||||
// Description:
|
|
||||||
// Adds a callback to be called when the meta data of this asset changed.
|
|
||||||
// Arguments:
|
|
||||||
// callBack - A functor to be added
|
|
||||||
// Return Value:
|
|
||||||
// True if successful, false otherwise.
|
|
||||||
// See Also:
|
|
||||||
// RemoveMetaDataChangeListener()
|
|
||||||
virtual bool AddMetaDataChangeListener(MetaDataChangeListener callBack) = 0;
|
|
||||||
// Description:
|
|
||||||
// Removes a callback from the list of meta data change listeners.
|
|
||||||
// Arguments:
|
|
||||||
// callBack - A functor to be removed
|
|
||||||
// Return Value:
|
|
||||||
// True if successful, false otherwise.
|
|
||||||
// See Also:
|
|
||||||
// AddMetaDataCHangeListener()
|
|
||||||
virtual bool RemoveMetaDataChangeListener(MetaDataChangeListener callBack) = 0;
|
|
||||||
// Description:
|
|
||||||
// The method that should be called when the meta data of an asset item changes to notify all listeners
|
|
||||||
// Arguments:
|
|
||||||
// pAssetItem - An asset item whose meta data have changed
|
|
||||||
// See Also:
|
|
||||||
// AddMetaDataCHangeListener(), RemoveMetaDataChangeListener()
|
|
||||||
virtual void OnMetaDataChange(const IAssetItem* pAssetItem) = 0;
|
|
||||||
|
|
||||||
//! from IUnknown
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface([[maybe_unused]] REFIID riid, [[maybe_unused]] void** ppvObject)
|
|
||||||
{
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
};
|
|
||||||
virtual ULONG STDMETHODCALLTYPE AddRef()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
virtual ULONG STDMETHODCALLTYPE Release()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
#endif // CRYINCLUDE_EDITOR_INCLUDE_IASSETITEMDATABASE_H
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// Description : This file declares a control which objective is to display
|
|
||||||
// multiple assets allowing selection and preview of such things
|
|
||||||
// It also handles scrolling and changes in the thumbnail display size
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IASSETVIEWER_H
|
|
||||||
#define CRYINCLUDE_EDITOR_INCLUDE_IASSETVIEWER_H
|
|
||||||
#pragma once
|
|
||||||
#include "IObservable.h"
|
|
||||||
#include "IAssetItemDatabase.h"
|
|
||||||
|
|
||||||
struct IAssetItem;
|
|
||||||
struct IAssetItemDatabase;
|
|
||||||
|
|
||||||
// Description:
|
|
||||||
// Observer for the asset viewer events
|
|
||||||
struct IAssetViewerObserver
|
|
||||||
{
|
|
||||||
virtual void OnChangeStatusBarInfo(UINT nSelectedItems, UINT nVisibleItems, UINT nTotalItems) {};
|
|
||||||
virtual void OnSelectionChanged() {};
|
|
||||||
virtual void OnChangedPreviewedAsset(IAssetItem* pAsset) {};
|
|
||||||
virtual void OnAssetDblClick(IAssetItem* pAsset) {};
|
|
||||||
virtual void OnAssetFilterChanged() {};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Description:
|
|
||||||
// The asset viewer interface for the asset database plugins to use
|
|
||||||
struct IAssetViewer
|
|
||||||
{
|
|
||||||
DEFINE_OBSERVABLE_PURE_METHODS(IAssetViewerObserver);
|
|
||||||
|
|
||||||
virtual HWND GetRenderWindow() = 0;
|
|
||||||
virtual void ApplyFilters(const IAssetItemDatabase::TAssetFieldFiltersMap& rFieldFilters) = 0;
|
|
||||||
virtual const IAssetItemDatabase::TAssetFieldFiltersMap& GetCurrentFilters() = 0;
|
|
||||||
virtual void ClearFilters() = 0;
|
|
||||||
};
|
|
||||||
#endif // CRYINCLUDE_EDITOR_INCLUDE_IASSETVIEWER_H
|
|
||||||
@ -1,506 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "EditorDefs.h"
|
|
||||||
|
|
||||||
#include "SimpleTriangleRasterizer.h"
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#if !defined FLT_MAX
|
|
||||||
#define FLT_MAX 3.402823466e+38F
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void CSimpleTriangleRasterizer::lambertHorizlineConservative(float fx1, float fx2, int yy, IRasterizeSink* inpSink)
|
|
||||||
{
|
|
||||||
int x1 = (int)floorf(fx1 + 0.25f), x2 = (int)floorf(fx2 + .75f);
|
|
||||||
|
|
||||||
if (x1 < m_iMinX)
|
|
||||||
{
|
|
||||||
x1 = m_iMinX;
|
|
||||||
}
|
|
||||||
if (x2 > m_iMaxX + 1)
|
|
||||||
{
|
|
||||||
x2 = m_iMaxX + 1;
|
|
||||||
}
|
|
||||||
if (x1 > m_iMaxX + 1)
|
|
||||||
{
|
|
||||||
x1 = m_iMaxX + 1;
|
|
||||||
}
|
|
||||||
if (x2 < m_iMinX)
|
|
||||||
{
|
|
||||||
x2 = m_iMinX;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inpSink->Line(fx1, fx2, x1, x2, yy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSimpleTriangleRasterizer::lambertHorizlineSubpixelCorrect(float fx1, float fx2, int yy, IRasterizeSink* inpSink)
|
|
||||||
{
|
|
||||||
int x1 = (int)floorf(fx1 + 0.5f), x2 = (int)floorf(fx2 + 0.5f);
|
|
||||||
// int x1=(int)floorf(fx1*1023.f/1024.f+1.f),x2=(int)floorf(fx2*1023.f/1024.f+1.f);
|
|
||||||
|
|
||||||
if (x1 < m_iMinX)
|
|
||||||
{
|
|
||||||
x1 = m_iMinX;
|
|
||||||
}
|
|
||||||
if (x2 > m_iMaxX)
|
|
||||||
{
|
|
||||||
x2 = m_iMaxX;
|
|
||||||
}
|
|
||||||
if (x1 > m_iMaxX)
|
|
||||||
{
|
|
||||||
x1 = m_iMaxX;
|
|
||||||
}
|
|
||||||
if (x2 < m_iMinX)
|
|
||||||
{
|
|
||||||
x2 = m_iMinX;
|
|
||||||
}
|
|
||||||
|
|
||||||
inpSink->Line(fx1, fx2, x1, x2, yy);
|
|
||||||
}
|
|
||||||
|
|
||||||
// optimizable
|
|
||||||
void CSimpleTriangleRasterizer::CopyAndSortY(const float infX[3], const float infY[3], float outfX[3], float outfY[3])
|
|
||||||
{
|
|
||||||
outfX[0] = infX[0];
|
|
||||||
outfY[0] = infY[0];
|
|
||||||
outfX[1] = infX[1];
|
|
||||||
outfY[1] = infY[1];
|
|
||||||
outfX[2] = infX[2];
|
|
||||||
outfY[2] = infY[2];
|
|
||||||
|
|
||||||
// Sort the coordinates, so that (x[1], y[1]) becomes the highest coord
|
|
||||||
float tmp;
|
|
||||||
|
|
||||||
if (outfY[0] > outfY[1])
|
|
||||||
{
|
|
||||||
if (outfY[1] > outfY[2])
|
|
||||||
{
|
|
||||||
tmp = outfY[0];
|
|
||||||
outfY[0] = outfY[1];
|
|
||||||
outfY[1] = tmp;
|
|
||||||
tmp = outfX[0];
|
|
||||||
outfX[0] = outfX[1];
|
|
||||||
outfX[1] = tmp;
|
|
||||||
tmp = outfY[1];
|
|
||||||
outfY[1] = outfY[2];
|
|
||||||
outfY[2] = tmp;
|
|
||||||
tmp = outfX[1];
|
|
||||||
outfX[1] = outfX[2];
|
|
||||||
outfX[2] = tmp;
|
|
||||||
|
|
||||||
if (outfY[0] > outfY[1])
|
|
||||||
{
|
|
||||||
tmp = outfY[0];
|
|
||||||
outfY[0] = outfY[1];
|
|
||||||
outfY[1] = tmp;
|
|
||||||
tmp = outfX[0];
|
|
||||||
outfX[0] = outfX[1];
|
|
||||||
outfX[1] = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tmp = outfY[0];
|
|
||||||
outfY[0] = outfY[1];
|
|
||||||
outfY[1] = tmp;
|
|
||||||
tmp = outfX[0];
|
|
||||||
outfX[0] = outfX[1];
|
|
||||||
outfX[1] = tmp;
|
|
||||||
|
|
||||||
if (outfY[1] > outfY[2])
|
|
||||||
{
|
|
||||||
tmp = outfY[1];
|
|
||||||
outfY[1] = outfY[2];
|
|
||||||
outfY[2] = tmp;
|
|
||||||
tmp = outfX[1];
|
|
||||||
outfX[1] = outfX[2];
|
|
||||||
outfX[2] = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (outfY[1] > outfY[2])
|
|
||||||
{
|
|
||||||
tmp = outfY[1];
|
|
||||||
outfY[1] = outfY[2];
|
|
||||||
outfY[2] = tmp;
|
|
||||||
tmp = outfX[1];
|
|
||||||
outfX[1] = outfX[2];
|
|
||||||
outfX[2] = tmp;
|
|
||||||
|
|
||||||
if (outfY[0] > outfY[1])
|
|
||||||
{
|
|
||||||
tmp = outfY[0];
|
|
||||||
outfY[0] = outfY[1];
|
|
||||||
outfY[1] = tmp;
|
|
||||||
tmp = outfX[0];
|
|
||||||
outfX[0] = outfX[1];
|
|
||||||
outfX[1] = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSimpleTriangleRasterizer::CallbackFillRectConservative(float _x[3], float _y[3], IRasterizeSink* inpSink)
|
|
||||||
{
|
|
||||||
inpSink->Triangle(m_iMinY);
|
|
||||||
|
|
||||||
float fMinX = (std::min)(_x[0], (std::min)(_x[1], _x[2]));
|
|
||||||
float fMaxX = (std::max)(_x[0], (std::max)(_x[1], _x[2]));
|
|
||||||
float fMinY = (std::min)(_y[0], (std::min)(_y[1], _y[2]));
|
|
||||||
float fMaxY = (std::max)(_y[0], (std::max)(_y[1], _y[2]));
|
|
||||||
|
|
||||||
int iMinX = (std::max)(m_iMinX, (int)floorf(fMinX));
|
|
||||||
int iMaxX = (std::min)(m_iMaxX + 1, (int)ceilf(fMaxX));
|
|
||||||
int iMinY = (std::max)(m_iMinY, (int)floorf(fMinY));
|
|
||||||
int iMaxY = (std::min)(m_iMaxY + 1, (int)ceilf(fMaxY));
|
|
||||||
|
|
||||||
for (int y = iMinY; y < iMaxY; y++)
|
|
||||||
{
|
|
||||||
inpSink->Line(fMinX, fMaxX, iMinX, iMaxX, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CSimpleTriangleRasterizer::CallbackFillConservative(float _x[3], float _y[3], IRasterizeSink* inpSink)
|
|
||||||
{
|
|
||||||
float x[3], y[3];
|
|
||||||
|
|
||||||
CopyAndSortY(_x, _y, x, y);
|
|
||||||
|
|
||||||
// Calculate interpolation steps
|
|
||||||
float fX1toX2step = 0.0f;
|
|
||||||
float fX1toX3step = 0.0f;
|
|
||||||
float fX2toX3step = 0.0f;
|
|
||||||
if (fabsf(y[1] - y[0]) > FLT_EPSILON)
|
|
||||||
{
|
|
||||||
fX1toX2step = (x[1] - x[0]) / (float)(y[1] - y[0]);
|
|
||||||
}
|
|
||||||
if (fabsf(y[2] - y[0]) > FLT_EPSILON)
|
|
||||||
{
|
|
||||||
fX1toX3step = (x[2] - x[0]) / (float)(y[2] - y[0]);
|
|
||||||
}
|
|
||||||
if (fabsf(y[2] - y[1]) > FLT_EPSILON)
|
|
||||||
{
|
|
||||||
fX2toX3step = (x[2] - x[1]) / (float)(y[2] - y[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
float fX1toX2 = x[0], fX1toX3 = x[0], fX2toX3 = x[1];
|
|
||||||
bool bFirstLine = true;
|
|
||||||
bool bTriangleCallDone = false;
|
|
||||||
|
|
||||||
// Go through the scanlines of the triangle
|
|
||||||
int yy = (int)floorf(y[0]); // was floor
|
|
||||||
|
|
||||||
for (; yy <= (int)floorf(y[2]); yy++)
|
|
||||||
// for(yy=m_iMinY; yy<=m_iMaxY; yy++) // juhu
|
|
||||||
{
|
|
||||||
float fSubPixelYStart = 0.0f, fSubPixelYEnd = 1.0f;
|
|
||||||
float start, end;
|
|
||||||
|
|
||||||
// first line
|
|
||||||
if (bFirstLine)
|
|
||||||
{
|
|
||||||
fSubPixelYStart = y[0] - floorf(y[0]);
|
|
||||||
start = x[0];
|
|
||||||
end = x[0];
|
|
||||||
bFirstLine = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// top part without middle corner line
|
|
||||||
if (yy <= (int)floorf(y[1]))
|
|
||||||
{
|
|
||||||
start = (std::min)(fX1toX2, fX1toX3);
|
|
||||||
end = (std::max)(fX1toX2, fX1toX3);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
start = (std::min)(fX2toX3, fX1toX3);
|
|
||||||
end = (std::max)(fX2toX3, fX1toX3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// middle corner line
|
|
||||||
if (yy == (int)floorf(y[1]))
|
|
||||||
{
|
|
||||||
fSubPixelYEnd = y[1] - floorf(y[1]);
|
|
||||||
|
|
||||||
fX1toX3 += fX1toX3step * (fSubPixelYEnd - fSubPixelYStart);
|
|
||||||
start = (std::min)(start, fX1toX3);
|
|
||||||
end = (std::max)(end, fX1toX3);
|
|
||||||
start = (std::min)(start, x[1]);
|
|
||||||
end = (std::max)(end, x[1]);
|
|
||||||
|
|
||||||
fSubPixelYStart = fSubPixelYEnd;
|
|
||||||
fSubPixelYEnd = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// last line
|
|
||||||
if (yy == (int)floorf(y[2]))
|
|
||||||
{
|
|
||||||
start = (std::min)(start, x[2]);
|
|
||||||
end = (std::max)(end, x[2]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// top part without middle corner line
|
|
||||||
if (yy < (int)floorf(y[1]))
|
|
||||||
{
|
|
||||||
fX1toX2 += fX1toX2step * (fSubPixelYEnd - fSubPixelYStart);
|
|
||||||
start = (std::min)(start, fX1toX2);
|
|
||||||
end = (std::max)(end, fX1toX2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fX2toX3 += fX2toX3step * (fSubPixelYEnd - fSubPixelYStart);
|
|
||||||
start = (std::min)(start, fX2toX3);
|
|
||||||
end = (std::max)(end, fX2toX3);
|
|
||||||
}
|
|
||||||
|
|
||||||
fX1toX3 += fX1toX3step * (fSubPixelYEnd - fSubPixelYStart);
|
|
||||||
start = (std::min)(start, fX1toX3);
|
|
||||||
end = (std::max)(end, fX1toX3);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (yy >= m_iMinY && yy <= m_iMaxY)
|
|
||||||
{
|
|
||||||
if (!bTriangleCallDone)
|
|
||||||
{
|
|
||||||
inpSink->Triangle(yy);
|
|
||||||
bTriangleCallDone = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
lambertHorizlineConservative(start, end, yy, inpSink);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CSimpleTriangleRasterizer::CallbackFillSubpixelCorrect(float _x[3], float _y[3], IRasterizeSink* inpSink)
|
|
||||||
{
|
|
||||||
float x[3], y[3];
|
|
||||||
|
|
||||||
CopyAndSortY(_x, _y, x, y);
|
|
||||||
|
|
||||||
if (fabs(y[0] - floorf(y[0])) < FLT_EPSILON)
|
|
||||||
{
|
|
||||||
y[0] -= FLT_EPSILON;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate interpolation steps
|
|
||||||
float fX1toX2step = 0.0f;
|
|
||||||
float fX1toX3step = 0.0f;
|
|
||||||
float fX2toX3step = 0.0f;
|
|
||||||
if (fabsf(y[1] - y[0]) > FLT_EPSILON)
|
|
||||||
{
|
|
||||||
fX1toX2step = (x[1] - x[0]) / (y[1] - y[0]);
|
|
||||||
}
|
|
||||||
if (fabsf(y[2] - y[0]) > FLT_EPSILON)
|
|
||||||
{
|
|
||||||
fX1toX3step = (x[2] - x[0]) / (y[2] - y[0]);
|
|
||||||
}
|
|
||||||
if (fabsf(y[2] - y[1]) > FLT_EPSILON)
|
|
||||||
{
|
|
||||||
fX2toX3step = (x[2] - x[1]) / (y[2] - y[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
float fX1toX2 = x[0], fX1toX3 = x[0], fX2toX3 = x[1];
|
|
||||||
bool bFirstLine = true;
|
|
||||||
bool bTriangleCallDone = false;
|
|
||||||
|
|
||||||
y[0] -= 0.5f;
|
|
||||||
y[1] -= 0.5f;
|
|
||||||
y[2] -= 0.5f;
|
|
||||||
// y[0]=y[0]*1023.f/1024.f+1.f;
|
|
||||||
// y[1]=y[1]*1023.f/1024.f+1.f;
|
|
||||||
// y[2]=y[2]*1023.f/1024.f+1.f;
|
|
||||||
|
|
||||||
for (int yy = (int)floorf(y[0]); yy <= (int)floorf(y[2]); yy++)
|
|
||||||
{
|
|
||||||
float fSubPixelYStart = 0.0f, fSubPixelYEnd = 1.0f;
|
|
||||||
float start, end;
|
|
||||||
|
|
||||||
// first line
|
|
||||||
if (bFirstLine)
|
|
||||||
{
|
|
||||||
fSubPixelYStart = y[0] - floorf(y[0]);
|
|
||||||
start = x[0];
|
|
||||||
end = x[0];
|
|
||||||
bFirstLine = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// top part without middle corner line
|
|
||||||
if (yy <= (int)floorf(y[1]))
|
|
||||||
{
|
|
||||||
start = (std::min)(fX1toX2, fX1toX3);
|
|
||||||
end = (std::max)(fX1toX2, fX1toX3);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
start = (std::min)(fX2toX3, fX1toX3);
|
|
||||||
end = (std::max)(fX2toX3, fX1toX3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// middle corner line
|
|
||||||
if (yy == (int)floorf(y[1]))
|
|
||||||
{
|
|
||||||
fSubPixelYEnd = y[1] - floorf(y[1]);
|
|
||||||
|
|
||||||
fX1toX3 += fX1toX3step * (fSubPixelYEnd - fSubPixelYStart);
|
|
||||||
|
|
||||||
fSubPixelYStart = fSubPixelYEnd;
|
|
||||||
fSubPixelYEnd = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// last line
|
|
||||||
if (yy != (int)floorf(y[2]))
|
|
||||||
{
|
|
||||||
// top part without middle corner line
|
|
||||||
if (yy < (int)floorf(y[1]))
|
|
||||||
{
|
|
||||||
fX1toX2 += fX1toX2step * (fSubPixelYEnd - fSubPixelYStart);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fX2toX3 += fX2toX3step * (fSubPixelYEnd - fSubPixelYStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
fX1toX3 += fX1toX3step * (fSubPixelYEnd - fSubPixelYStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start != end)
|
|
||||||
{
|
|
||||||
if (yy >= m_iMinY && yy <= m_iMaxY)
|
|
||||||
{
|
|
||||||
if (!bTriangleCallDone)
|
|
||||||
{
|
|
||||||
inpSink->Triangle(yy);
|
|
||||||
bTriangleCallDone = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
lambertHorizlineSubpixelCorrect(start, end, yy, inpSink);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// shrink triangle by n pixel, optimizable
|
|
||||||
void CSimpleTriangleRasterizer::ShrinkTriangle(float inoutfX[3], float inoutfY[3], float infAmount)
|
|
||||||
{
|
|
||||||
float fX[3] = { inoutfX[0], inoutfX[1], inoutfX[2] };
|
|
||||||
float fY[3] = { inoutfY[0], inoutfY[1], inoutfY[2] };
|
|
||||||
|
|
||||||
/*
|
|
||||||
// move edge to opposing vertex
|
|
||||||
float dx,dy,fLength;
|
|
||||||
|
|
||||||
for(int a=0;a<3;a++)
|
|
||||||
{
|
|
||||||
int b=a+1;if(b>=3)b=0;
|
|
||||||
int c=b+1;if(c>=3)c=0;
|
|
||||||
|
|
||||||
dx=fX[a]-(fX[b]+fX[c])*0.5f;
|
|
||||||
dy=fY[a]-(fY[b]+fY[c])*0.5f;
|
|
||||||
fLength=(float)sqrt(dx*dx+dy*dy);
|
|
||||||
if(fLength>1.0f)
|
|
||||||
{
|
|
||||||
dx/=fLength;dy/=fLength;
|
|
||||||
inoutfX[b]+=dx;inoutfY[b]+=dy;
|
|
||||||
inoutfX[c]+=dx;inoutfY[c]+=dy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
// move vertex to opposing edge
|
|
||||||
float dx,dy,fLength;
|
|
||||||
|
|
||||||
for(int a=0;a<3;a++)
|
|
||||||
{
|
|
||||||
int b=a+1;if(b>=3)b=0;
|
|
||||||
int c=b+1;if(c>=3)c=0;
|
|
||||||
|
|
||||||
dx=fX[a]-(fX[b]+fX[c])*0.5f;
|
|
||||||
dy=fY[a]-(fY[b]+fY[c])*0.5f;
|
|
||||||
fLength=(float)sqrt(dx*dx+dy*dy);
|
|
||||||
if(fLength>1.0f)
|
|
||||||
{
|
|
||||||
dx/=fLength;dy/=fLength;
|
|
||||||
inoutfX[a]-=dx;inoutfY[a]-=dy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// move vertex to get edges shifted perpendicular for 1 unit
|
|
||||||
for (int a = 0; a < 3; a++)
|
|
||||||
{
|
|
||||||
float dx1, dy1, dx2, dy2, fLength;
|
|
||||||
|
|
||||||
int b = a + 1;
|
|
||||||
if (b >= 3)
|
|
||||||
{
|
|
||||||
b = 0;
|
|
||||||
}
|
|
||||||
int c = b + 1;
|
|
||||||
if (c >= 3)
|
|
||||||
{
|
|
||||||
c = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dx1 = fX[b] - fX[a];
|
|
||||||
dy1 = fY[b] - fY[a];
|
|
||||||
fLength = (float)sqrt(dx1 * dx1 + dy1 * dy1);
|
|
||||||
if (infAmount > 0)
|
|
||||||
{
|
|
||||||
if (fLength < infAmount)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fLength == 0.0f)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
dx1 /= fLength;
|
|
||||||
dy1 /= fLength;
|
|
||||||
|
|
||||||
dx2 = fX[c] - fX[a];
|
|
||||||
dy2 = fY[c] - fY[a];
|
|
||||||
fLength = (float)sqrt(dx2 * dx2 + dy2 * dy2);
|
|
||||||
if (infAmount > 0)
|
|
||||||
{
|
|
||||||
if (fLength < infAmount)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fLength == 0.0f)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
dx2 /= fLength;
|
|
||||||
dy2 /= fLength;
|
|
||||||
|
|
||||||
inoutfX[a] += (dx1 + dx2) * infAmount;
|
|
||||||
inoutfY[a] += (dy1 + dy2) * infAmount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,181 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
||||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CRYINCLUDE_EDITOR_LIGHTMAPCOMPILER_SIMPLETRIANGLERASTERIZER_H
|
|
||||||
#define CRYINCLUDE_EDITOR_LIGHTMAPCOMPILER_SIMPLETRIANGLERASTERIZER_H
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
class CSimpleTriangleRasterizer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
class IRasterizeSink
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! is called once per triangel for the first possible visible line
|
|
||||||
//! /param iniStartY
|
|
||||||
virtual void Triangle([[maybe_unused]] const int iniStartY)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//! callback function
|
|
||||||
//! /param infXLeft included - not clipped against left and reight border
|
|
||||||
//! /param infXRight excluded - not clipped against left and reight border
|
|
||||||
//! /param iniXLeft included
|
|
||||||
//! /param iniXRight excluded
|
|
||||||
//! /param iniY
|
|
||||||
virtual void Line(const float infXLeft, const float infXRight,
|
|
||||||
const int iniXLeft, const int iniXRight, const int iniY) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef unsigned long DWORD;
|
|
||||||
|
|
||||||
// -----------------------------------------------------
|
|
||||||
|
|
||||||
//! implementation sink sample
|
|
||||||
class CDWORDFlatFill
|
|
||||||
: public IRasterizeSink
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! constructor
|
|
||||||
CDWORDFlatFill(DWORD* inpBuffer, const DWORD indwPitchInPixels, DWORD indwValue)
|
|
||||||
{
|
|
||||||
m_dwValue = indwValue;
|
|
||||||
m_pBuffer = inpBuffer;
|
|
||||||
m_dwPitchInPixels = indwPitchInPixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Triangle(const int iniY)
|
|
||||||
{
|
|
||||||
m_pBufferLine = &m_pBuffer[iniY * m_dwPitchInPixels];
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Line([[maybe_unused]] const float infXLeft, [[maybe_unused]] const float infXRight,
|
|
||||||
const int iniLeft, const int iniRight, [[maybe_unused]] const int iniY)
|
|
||||||
{
|
|
||||||
DWORD* mem = &m_pBufferLine[iniLeft];
|
|
||||||
|
|
||||||
for (int x = iniLeft; x < iniRight; x++)
|
|
||||||
{
|
|
||||||
*mem++ = m_dwValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pBufferLine += m_dwPitchInPixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
DWORD m_dwValue; //!< fill value
|
|
||||||
DWORD* m_pBufferLine; //!< to get rid of the multiplication per line
|
|
||||||
|
|
||||||
DWORD m_dwPitchInPixels; //!< in DWORDS, not in Bytes
|
|
||||||
DWORD* m_pBuffer; //!< pointer to the buffer
|
|
||||||
};
|
|
||||||
|
|
||||||
// -----------------------------------------------------
|
|
||||||
|
|
||||||
//! constructor
|
|
||||||
//! /param iniWidth excluded
|
|
||||||
//! /param iniHeight excluded
|
|
||||||
CSimpleTriangleRasterizer(const int iniWidth, const int iniHeight)
|
|
||||||
{
|
|
||||||
m_iMinX = 0;
|
|
||||||
m_iMinY = 0;
|
|
||||||
m_iMaxX = iniWidth - 1;
|
|
||||||
m_iMaxY = iniHeight - 1;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
//! constructor
|
|
||||||
//! /param iniMinX included
|
|
||||||
//! /param iniMinY included
|
|
||||||
//! /param iniMaxX included
|
|
||||||
//! /param iniMaxY included
|
|
||||||
CSimpleTriangleRasterizer( const int iniMinX, const int iniMinY, const int iniMaxX, const int iniMaxY )
|
|
||||||
{
|
|
||||||
m_iMinX=iniMinX;
|
|
||||||
m_iMinY=iniMinY;
|
|
||||||
m_iMaxX=iniMaxX;
|
|
||||||
m_iMaxY=iniMaxY;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//! simple triangle filler with clipping (optimizable), not subpixel correct
|
|
||||||
//! /param pBuffer pointer o the color buffer
|
|
||||||
//! /param indwWidth width of the color buffer
|
|
||||||
//! /param indwHeight height of the color buffer
|
|
||||||
//! /param x array of the x coordiantes of the three vertices
|
|
||||||
//! /param y array of the x coordiantes of the three vertices
|
|
||||||
//! /param indwValue value of the triangle
|
|
||||||
void DWORDFlatFill(DWORD* inpBuffer, const DWORD indwPitchInPixels, float x[3], float y[3], DWORD indwValue, bool inbConservative)
|
|
||||||
{
|
|
||||||
CDWORDFlatFill pix(inpBuffer, indwPitchInPixels, indwValue);
|
|
||||||
|
|
||||||
if (inbConservative)
|
|
||||||
{
|
|
||||||
CallbackFillConservative(x, y, &pix);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CallbackFillSubpixelCorrect(x, y, &pix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rectangle around triangle - more stable - use for debugging purpose
|
|
||||||
void CallbackFillRectConservative(float x[3], float y[3], IRasterizeSink * inpSink);
|
|
||||||
|
|
||||||
|
|
||||||
//! subpixel correct triangle filler (conservative or not conservative)
|
|
||||||
//! \param pBuffer pointe to the DWORD
|
|
||||||
//! \param indwWidth width of the buffer pBuffer pointes to
|
|
||||||
//! \param indwHeight height of the buffer pBuffer pointes to
|
|
||||||
//! \param x array of the x coordiantes of the three vertices
|
|
||||||
//! \param y array of the x coordiantes of the three vertices
|
|
||||||
//! \param inpSink pointer to the sink interface (is called per triangle and per triangle line)
|
|
||||||
void CallbackFillConservative(float x[3], float y[3], IRasterizeSink * inpSink);
|
|
||||||
|
|
||||||
//! subpixel correct triangle filler (conservative or not conservative)
|
|
||||||
//! \param pBuffer pointe to the DWORD
|
|
||||||
//! \param indwWidth width of the buffer pBuffer pointes to
|
|
||||||
//! \param indwHeight height of the buffer pBuffer pointes to
|
|
||||||
//! \param x array of the x coordiantes of the three vertices
|
|
||||||
//! \param y array of the x coordiantes of the three vertices
|
|
||||||
//! \param inpSink pointer to the sink interface (is called per triangle and per triangle line)
|
|
||||||
void CallbackFillSubpixelCorrect(float x[3], float y[3], IRasterizeSink * inpSink);
|
|
||||||
|
|
||||||
//!
|
|
||||||
//! /param inoutfX
|
|
||||||
//! /param inoutfY
|
|
||||||
//! /param infAmount could be positive or negative
|
|
||||||
static void ShrinkTriangle(float inoutfX[3], float inoutfY[3], float infAmount);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Clipping Rect;
|
|
||||||
|
|
||||||
int m_iMinX; //!< minimum x value included
|
|
||||||
int m_iMinY; //!< minimum y value included
|
|
||||||
int m_iMaxX; //!< maximum x value included
|
|
||||||
int m_iMaxY; //!< maximum x value included
|
|
||||||
|
|
||||||
void lambertHorizlineConservative(float fx1, float fx2, int y, IRasterizeSink* inpSink);
|
|
||||||
void lambertHorizlineSubpixelCorrect(float fx1, float fx2, int y, IRasterizeSink* inpSink);
|
|
||||||
void CopyAndSortY(const float infX[3], const float infY[3], float outfX[3], float outfY[3]);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// extension ideas:
|
|
||||||
// * callback with coverage mask (possible non ordered sampling)
|
|
||||||
// * z-buffer behaviour
|
|
||||||
// * gouraud shading
|
|
||||||
// * texture mapping with nearest/bicubic/bilinear filter
|
|
||||||
// * further primitives: thick line, ellipse
|
|
||||||
// * build a template version
|
|
||||||
// *
|
|
||||||
|
|
||||||
#endif // CRYINCLUDE_EDITOR_LIGHTMAPCOMPILER_SIMPLETRIANGLERASTERIZER_H
|
|
||||||
Loading…
Reference in New Issue