git mv Code\Sandbox\Editor Code/Editor

Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
Esteban Papp
2021-06-29 12:41:59 -07:00
parent 9f0bbf3b74
commit e34e36cb35
1415 changed files with 0 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+199
View File
@@ -0,0 +1,199 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
// Description : Manager for export geometry
#ifndef CRYINCLUDE_EDITOR_EXPORT_EXPORTMANAGER_H
#define CRYINCLUDE_EDITOR_EXPORT_EXPORTMANAGER_H
#pragma once
#include <AzCore/Component/EntityId.h>
#include <IExportManager.h>
class CExportManager;
class CTrackViewTrack;
class CTrackViewSequence;
class CTrackViewAnimNode;
class CEntityObject;
typedef std::vector<IExporter*> TExporters;
namespace Export
{
class CMesh
: public Mesh
, public CRefCountBase
{
public:
CMesh();
virtual int GetFaceCount() const { return m_faces.size(); }
virtual const Face* GetFaceBuffer() const { return m_faces.size() ? &m_faces[0] : 0; }
private:
std::vector<Face> m_faces;
friend CExportManager;
};
class CObject
: public Object
, public CRefCountBase
{
public:
CObject(const char* pName);
virtual int GetVertexCount() const { return m_vertices.size(); }
virtual const Vector3D* GetVertexBuffer() const{ return m_vertices.size() ? &m_vertices[0] : 0; }
virtual int GetNormalCount() const { return m_normals.size(); }
virtual const Vector3D* GetNormalBuffer() const { return m_normals.size() ? &m_normals[0] : 0; }
virtual int GetTexCoordCount() const { return m_texCoords.size(); }
virtual const UV* GetTexCoordBuffer() const { return m_texCoords.size() ? &m_texCoords[0] : 0; }
virtual int GetMeshCount() const { return m_meshes.size(); }
virtual Mesh* GetMesh(int index) const { return m_meshes[index]; }
virtual size_t MeshHash() const{return m_MeshHash; }
void SetMaterialName(const char* pName);
virtual int GetEntityAnimationDataCount() const {return m_entityAnimData.size(); }
virtual const EntityAnimData* GetEntityAnimationData(int index) const {return &m_entityAnimData[index]; }
virtual void SetEntityAnimationData(EntityAnimData entityData){ m_entityAnimData.push_back(entityData); };
void SetLastPtr(CBaseObject* pObject){m_pLastObject = pObject; };
CBaseObject* GetLastObjectPtr(){return m_pLastObject; };
private:
CBaseObject* m_pLastObject;
std::vector<Vector3D> m_vertices;
std::vector<Vector3D> m_normals;
std::vector<UV> m_texCoords;
std::vector< _smart_ptr<CMesh> > m_meshes;
std::vector<EntityAnimData> m_entityAnimData;
size_t m_MeshHash;
friend CExportManager;
};
class CData
: public IData
{
public:
virtual int GetObjectCount() const { return m_objects.size(); }
virtual Object* GetObject(int index) const { return m_objects[index]; }
virtual Object* AddObject(const char* objectName);
void Clear();
private:
std::vector< _smart_ptr<Export::CObject> > m_objects;
friend CExportManager;
};
}
typedef std::map<CBaseObject*, int> TObjectMap;
class CExportManager
: public IExportManager
{
public:
CExportManager();
virtual ~CExportManager();
//! Register exporter
//! return true if succeed, otherwise false
virtual bool RegisterExporter(IExporter* pExporter);
//! Export specified geometry
//! return true if succeed, otherwise false
bool Export(const char* defaultName, const char* defaultExt = "", const char* defaultPath = "", bool isSelectedObjects = true,
bool isSelectedRegionObjects = false, bool isOccluder = false, bool bAnimationExport = false);
bool AddSelectedEntityObjects();
//! Add to Export Data geometry from objects inside selected region volume
//! return true if succeed, otherwise false
bool AddSelectedRegionObjects();
//! Export to file collected data, using specified exporter throughout the file extension
//! return true if succeed, otherwise false
bool ExportToFile(const char* filename, bool bClearDataAfterExport = true);
bool ImportFromFile(const char* filename);
const Export::CData& GetData() const {return m_data; };
//! Exports the stat obj to the obj file specified
//! returns true if succeeded, otherwise false
virtual bool ExportSingleStatObj(IStatObj* pStatObj, const char* filename);
void SetBakedKeysSequenceExport(bool bBaked){m_bBakedKeysSequenceExport = bBaked; };
void SaveNodeKeysTimeToXML();
private:
void AddMesh(Export::CObject* pObj, const IIndexedMesh* pIndMesh, Matrix34A* pTm = 0);
bool AddStatObj(Export::CObject* pObj, IStatObj* pStatObj, Matrix34A* pTm = 0);
bool AddMeshes(Export::CObject* pObj);
bool AddObject(CBaseObject* pBaseObj);
void SolveHierarchy();
void AddEntityAnimationData(AZ::EntityId entityId);
void ProcessEntityAnimationTrack(AZ::EntityId entityId, Export::CObject* pObj, AnimParamType entityTrackParamType);
void AddEntityAnimationData(const CTrackViewTrack* pTrack, Export::CObject* pObj, AnimParamType entityTrackParamType);
void AddPosRotScale(Export::CObject* pObj, const CBaseObject* pBaseObj);
void AddEntityData(Export::CObject* pObj, Export::AnimParamType dataType, const float fValue, const float fTime);
bool AddObjectsFromSequence(CTrackViewSequence* pSequence, XmlNodeRef seqNode = 0);
bool IsDuplicateObjectBeingAdded(const QString& newObject);
void SetFBXExportSettings(bool bLocalCoordsToSelectedObject, bool bExportOnlyPrimaryCamera, const float fps);
bool ProcessObjectsForExport();
bool ShowFBXExportDialog();
void FillAnimTimeNode(XmlNodeRef writeNode, CTrackViewAnimNode* pObjectNode, CTrackViewSequence* currentSequence);
QString CleanXMLText(const QString& text);
private:
TExporters m_exporters;
Export::CData m_data;
bool m_isPrecaching;
bool m_isOccluder;
float m_fScale;
TObjectMap m_objectMap;
bool m_bAnimationExport;
CBaseObject* m_pBaseObj;
float m_FBXBakedExportFPS;
bool m_bExportLocalCoords;
bool m_bExportOnlyPrimaryCamera;
int m_numberOfExportFrames;
CEntityObject* m_pivotEntityObject;
bool m_bBakedKeysSequenceExport;
QString m_animTimeExportPrimarySequenceName;
float m_animTimeExportPrimarySequenceCurrentTime;
XmlNodeRef m_animTimeNode;
bool m_animKeyTimeExport;
bool m_soundKeyTimeExport;
};
#endif // CRYINCLUDE_EDITOR_EXPORT_EXPORTMANAGER_H
+283
View File
@@ -0,0 +1,283 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "OBJExporter.h"
const char* COBJExporter::GetExtension() const
{
return "obj";
}
const char* COBJExporter::GetShortDescription() const
{
return "Object files";
}
bool COBJExporter::ExportToFile(const char* filename, const Export::IData* pExportData)
{
CLogFile::FormatLine("Exporting OBJ file to '%s'", filename);
FILE* hFile = nullptr;
azfopen(&hFile, filename, "w");
if (!hFile)
{
CLogFile::FormatLine("Error while opening file '%s'!", filename);
assert(hFile);
return false;
}
// Write header
fprintf(hFile, "# Object file exported by Sandbox\n");
fprintf(hFile, "# Attention: while import to 3DS Max Unify checkbox for normals must be unchecked.\n");
fprintf(hFile, "#\n");
// Create MTL library filename
QString materialFilename = filename;
materialFilename = Path::ReplaceExtension(materialFilename, "mtl");
materialFilename = Path::GetFile(materialFilename);
// Write material library import statement
fprintf(hFile, "mtllib %s\n", materialFilename.toUtf8().data());
fprintf(hFile, "#\n");
int numObjects = pExportData->GetObjectCount();
for (int i = 0; i < numObjects; ++i)
{
const Export::Object* pObj = pExportData->GetObject(i);
Vec3 pos(pObj->pos.x, pObj->pos.y, pObj->pos.z);
Quat rot(pObj->rot.w, pObj->rot.v.x, pObj->rot.v.y, pObj->rot.v.z);
Vec3 scale(pObj->scale.x, pObj->scale.y, pObj->scale.z);
Matrix34 tm = Matrix33::CreateScale(scale) * Matrix34(rot);
tm.SetTranslation(pos);
int nParent = pObj->nParent;
while (nParent >= 0 && nParent < pExportData->GetObjectCount())
{
const Export::Object* pParentObj = pExportData->GetObject(nParent);
assert(NULL != pParentObj);
Vec3 pos2(pParentObj->pos.x, pParentObj->pos.y, pParentObj->pos.z);
Quat rot2(pParentObj->rot.w, pParentObj->rot.v.x, pParentObj->rot.v.y, pParentObj->rot.v.z);
Vec3 scale2(pParentObj->scale.x, pParentObj->scale.y, pParentObj->scale.z);
Matrix34 parentTm = Matrix33::CreateScale(scale2) * Matrix34(rot2);
parentTm.SetScale(scale2);
parentTm.SetTranslation(pos2);
tm = tm * parentTm;
nParent = pParentObj->nParent;
}
fprintf(hFile, "g %s\n", pObj->name); //For XSI
fprintf(hFile, "# object %s\n", pObj->name);
fprintf(hFile, "#\n");
int numVertices = pObj->GetVertexCount();
const Export::Vector3D* pVerts = pObj->GetVertexBuffer();
for (int ii = 0; ii < numVertices; ++ii)
{
const Export::Vector3D& vertex = pVerts[ii];
Vec3 vec(vertex.x, vertex.y, vertex.z);
vec = tm.TransformPoint(vec);
fprintf(hFile, "v %s %s %s\n", TrimFloat(vec.x), TrimFloat(vec.y), TrimFloat(vec.z));
}
fprintf(hFile, "# %i vertices\n\n", numVertices);
// Write object texture coordinates
int numTexCoords = pObj->GetTexCoordCount();
const Export::UV* pTexCoord = pObj->GetTexCoordBuffer();
for (int ii = 0; ii < numTexCoords; ++ii)
{
const Export::UV& textCoord = pTexCoord[ii];
fprintf(hFile, "vt %s %s 0\n", TrimFloat(textCoord.u), TrimFloat(textCoord.v));
}
fprintf(hFile, "# %i texture vertices\n\n", numTexCoords);
// Write object normals
int numNormals = pObj->GetNormalCount();
const Export::Vector3D* pNormals = pObj->GetNormalBuffer();
for (int ii = 0; ii < numNormals; ++ii)
{
const Export::Vector3D& normal = pNormals[ii];
fprintf(hFile, "vn %s %s %s\n", TrimFloat(normal.x), TrimFloat(normal.y), TrimFloat(normal.z));
}
fprintf(hFile, "# %i vertex normals\n\n", numNormals);
// Write submeshes
int numMeshes = pObj->GetMeshCount();
for (int j = 0; j < numMeshes; ++j)
{
const Export::Mesh* pMesh = pObj->GetMesh(j);
if (pMesh->material.name[0] != '\0')
{
fprintf(hFile, "usemtl %s\n", pMesh->material.name);
}
// TODO: if it's a smoth group fix it to bit difference
fprintf(hFile, "s %d\n", j);
// Write all faces, convert the indices to one based indices
int numFaces = pMesh->GetFaceCount();
const Export::Face* pFaceBuf = pMesh->GetFaceBuffer();
for (int ii = 0; ii < numFaces; ++ii)
{
const Export::Face& face = pFaceBuf[ii];
fprintf(hFile, "f %i/%i/%i %i/%i/%i %i/%i/%i\n",
face.idx[0] - numVertices, face.idx[0] - numTexCoords, face.idx[0] - numNormals,
face.idx[1] - numVertices, face.idx[1] - numTexCoords, face.idx[1] - numNormals,
face.idx[2] - numVertices, face.idx[2] - numTexCoords, face.idx[2] - numNormals);
}
fprintf(hFile, "# %i faces\n\n", numFaces);
}
}
fprintf(hFile, "g\n");
fclose(hFile);
// Export Material
materialFilename = Path::ReplaceExtension(filename, "mtl");
// Open the material file
hFile = nullptr;
azfopen(&hFile, materialFilename.toUtf8().data(), "w");
if (!hFile)
{
CLogFile::FormatLine("Error while opening file '%s'!", materialFilename.toUtf8().data());
assert(hFile);
return false;
}
// Write header
fprintf(hFile, "# Material file exported by Sandbox\n\n");
for (int i = 0; i < numObjects; ++i)
{
const Export::Object* pObj = pExportData->GetObject(i);
int numMeshes = pObj->GetMeshCount();
for (int j = 0; j < numMeshes; j++)
{
const Export::Mesh* pMesh = pObj->GetMesh(j);
if (pMesh->material.name[0] != '\0')
{
// Write material
const Export::Material& mtl = pMesh->material;
fprintf(hFile, "newmtl %s\n", mtl.name);
fprintf(hFile, "Ka %s %s %s\n", TrimFloat(mtl.diffuse.r), TrimFloat(mtl.diffuse.g), TrimFloat(mtl.diffuse.b));
fprintf(hFile, "Kd %s %s %s\n", TrimFloat(mtl.diffuse.r), TrimFloat(mtl.diffuse.g), TrimFloat(mtl.diffuse.b));
fprintf(hFile, "Ks %s %s %s\n", TrimFloat(mtl.specular.r), TrimFloat(mtl.specular.g), TrimFloat(mtl.specular.b));
fprintf(hFile, "d %s\n", TrimFloat(1.0f - mtl.opacity));
fprintf(hFile, "Tr %s\n", TrimFloat(1.0f - mtl.opacity));
fprintf(hFile, "Ns %s\n", TrimFloat(mtl.smoothness));
if (strlen(mtl.mapDiffuse))
{
fprintf(hFile, "map_Kd %s\n", MakeRelativePath(filename, mtl.mapDiffuse).toUtf8().constData());
}
if (strlen(mtl.mapSpecular))
{
fprintf(hFile, "map_Ns %s\n", MakeRelativePath(filename, mtl.mapSpecular).toUtf8().constData());
}
if (strlen(mtl.mapOpacity))
{
fprintf(hFile, "map_d %s\n", MakeRelativePath(filename, mtl.mapOpacity).toUtf8().constData());
}
if (strlen(mtl.mapNormals))
{
fprintf(hFile, "bump %s\n", MakeRelativePath(filename, mtl.mapNormals).toUtf8().constData());
}
if (strlen(mtl.mapDecal))
{
fprintf(hFile, "decal %s\n", MakeRelativePath(filename, mtl.mapDecal).toUtf8().constData());
}
if (strlen(mtl.mapDisplacement))
{
fprintf(hFile, "disp %s\n", MakeRelativePath(filename, mtl.mapDisplacement).toUtf8().constData());
}
fprintf(hFile, "\n");
}
}
}
fclose(hFile);
return true;
}
QString COBJExporter::MakeRelativePath(const char* pMainFileName, const char* pFileName) const
{
const char* ch = strrchr(pMainFileName, '\\');
if (ch)
{
if (strlen(pFileName) > ch - pMainFileName && !_strnicmp(pMainFileName, pFileName, ch - pMainFileName))
{
return QString(pFileName + (ch - pMainFileName) + 1);
}
}
return QString(pFileName);
}
const char* COBJExporter::TrimFloat(float fValue) const
{
// Convert a float into a string representation and remove all
// uneccessary zeroes and the decimal dot if it is not needed
const int nMaxAccessInTime = 4;
static char ppBufs[nMaxAccessInTime][16];
static int nCurBuf = 0;
if (nCurBuf >= nMaxAccessInTime)
{
nCurBuf = 0;
}
char* pBuf = ppBufs[nCurBuf];
size_t bufSize = sizeof(ppBufs[nCurBuf]);
++nCurBuf;
sprintf_s(pBuf, bufSize, "%f", fValue);
for (int i = strlen(pBuf) - 1; i > 0; --i)
{
if (pBuf[i] == '0')
{
pBuf[i] = 0;
}
else if (pBuf[i] == '.')
{
pBuf[i] = 0;
break;
}
else
{
break;
}
}
return pBuf;
}
void COBJExporter::Release()
{
delete this;
}
+36
View File
@@ -0,0 +1,36 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
// Description : Export geometry OBJ file format
#ifndef CRYINCLUDE_EDITOR_EXPORT_OBJEXPORTER_H
#define CRYINCLUDE_EDITOR_EXPORT_OBJEXPORTER_H
#pragma once
#include <IExportManager.h>
class COBJExporter
: public IExporter
{
public:
virtual const char* GetExtension() const;
virtual const char* GetShortDescription() const;
virtual bool ExportToFile(const char* filename, const Export::IData* pExportData);
virtual bool ImportFromFile([[maybe_unused]] const char* filename, [[maybe_unused]] Export::IData* pData){return false; };
virtual void Release();
private:
const char* TrimFloat(float fValue) const;
QString MakeRelativePath(const char* pMainFileName, const char* pFileName) const;
};
#endif // CRYINCLUDE_EDITOR_EXPORT_OBJEXPORTER_H
+290
View File
@@ -0,0 +1,290 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "OCMExporter.h"
class CFileEndianWriter
{
std::vector<uint8> m_Data;
size_t m_Offset;
public:
CFileEndianWriter()
: m_Offset(0){}
void Seek(size_t Offset){m_Offset = Offset; }
void Write(const void* pData, size_t Size)
{
if (m_Offset + Size > m_Data.size())
{
m_Data.resize(m_Offset + Size);
}
memcpy(&m_Data[m_Offset], pData, Size);
m_Offset += Size;
}
size_t Pos() const{return m_Offset; }
template<size_t Padding>
void Align(){m_Offset = (m_Offset + (Padding - 1)) & ~(Padding - 1); }
template<class T>
void Write(T D){Write(&D, sizeof(T)); }
const std::vector<uint8>& Data() const{return m_Data; }
};
const char* COCMExporter::GetExtension() const
{
return "ocm";
}
const char* COCMExporter::GetShortDescription() const
{
return "occlusion culler mesh";
}
Matrix44 MatRotate(f32 a, f32 b, f32 g)
{
const f32 CosR = cosf(a);
const f32 SinR = sinf(a);
const f32 CosP = cosf(b);
const f32 SinP = sinf(b);
const f32 CosY = cosf(g);
const f32 SinY = sinf(g);
const f32 SRSP = SinR * SinP;
const f32 CRSP = CosR * SinP;
Matrix44 Mat;
Mat.m00 = CosP * CosY;
Mat.m01 = CosP * SinY;
Mat.m02 = -SinP;
Mat.m03 = 0.f;
Mat.m10 = SRSP * CosY - CosR * SinY;
Mat.m11 = SRSP * SinY + CosR * CosY;
Mat.m12 = SinR * CosP;
Mat.m13 = 0.f;
Mat.m20 = CRSP * CosY + SinR * SinY;
Mat.m21 = CRSP * SinY - SinR * CosY;
Mat.m22 = CosR * CosP;
Mat.m23 = 0.f;
Mat.m30 = 0.f;
Mat.m31 = 0.f;
Mat.m32 = 0.f;
Mat.m33 = 1.f;
return Mat;
};
void COCMExporter::Extends(const Matrix44& rTransform, const Export::Object* pMesh, f32& rMinX, f32& rMaxX, f32& rMinY, f32& rMaxY, f32& rMinZ, f32& rMaxZ) const
{
rMinX = rMinY = rMinZ = FLT_MAX;
rMaxX = rMaxY = rMaxZ = -FLT_MAX;
const uint32 TriCount = pMesh->GetVertexCount();
const Export::Vector3D* pVerts = pMesh->GetVertexBuffer();
for (size_t a = 0; a < TriCount; a++)
{
const Export::Vector3D& rV = pVerts[a];
const Vec3 VO(rV.x, rV.y, rV.z);
const Vec3 V = rTransform.TransformPoint(VO);
rMinX = std::min(rMinX, V.x);
rMinY = std::min(rMinY, V.y);
rMinZ = std::min(rMinZ, V.z);
rMaxX = std::max(rMaxX, V.x);
rMaxY = std::max(rMaxY, V.y);
rMaxZ = std::max(rMaxZ, V.z);
}
}
Matrix44 COCMExporter::CalcOBB(const Export::Object* pMesh)
{
Matrix44 OBBMat(IDENTITY);
f32 MinX, MaxX, MinY, MaxY, MinZ, MaxZ;
Extends(OBBMat, pMesh, MinX, MaxX, MinY, MaxY, MinZ, MaxZ);
OBBMat.m03 = -(MaxX + MinX) * 0.5f;
OBBMat.m13 = -(MaxY + MinY) * 0.5f;
OBBMat.m23 = -(MaxZ + MinZ) * 0.5f;
return OBBMat;
}
size_t COCMExporter::SaveMesh(CFileEndianWriter& rWriter, const Export::Object* pMesh, Matrix44& rOBBMat)
{
const size_t PosStart = rWriter.Pos();
rOBBMat = CalcOBB(pMesh);
const Export::Vector3D* pVerts = pMesh->GetVertexBuffer();
std::vector<float> Pos;
const uint32 SubMeshCount = pMesh->GetMeshCount();
for (uint32 b = 0; b < SubMeshCount; b++)
{
const Export::Mesh* pSubMesh = pMesh->GetMesh(b);
const uint32 FaceCount = pSubMesh->GetFaceCount();
const Export::Face* pFaces = pSubMesh->GetFaceBuffer();
Pos.reserve(Pos.size() + FaceCount * 9);
for (size_t a = 0; a < FaceCount; a++)
{
const Export::Vector3D& rV0 = pVerts[pFaces[a].idx[0]];
const Export::Vector3D& rV1 = pVerts[pFaces[a].idx[1]];
const Export::Vector3D& rV2 = pVerts[pFaces[a].idx[2]];
const Vec3 VO0(rV0.x, rV0.y, rV0.z);
const Vec3 VO1(rV1.x, rV1.y, rV1.z);
const Vec3 VO2(rV2.x, rV2.y, rV2.z);
const Vec3 V0 = rOBBMat.TransformPoint(VO0);
const Vec3 V1 = rOBBMat.TransformPoint(VO1);
const Vec3 V2 = rOBBMat.TransformPoint(VO2);
const Vec3 N = (V2 - V0).cross(V1 - V0);
if (fabsf(N.dot(N)) <= FLT_EPSILON)//degenerated?
{
continue;
}
Pos.push_back(V0.x);
Pos.push_back(V0.y);
Pos.push_back(V0.z);
Pos.push_back(1.f);
Pos.push_back(V1.x);
Pos.push_back(V1.y);
Pos.push_back(V1.z);
Pos.push_back(1.f);
Pos.push_back(V2.x);
Pos.push_back(V2.y);
Pos.push_back(V2.z);
Pos.push_back(1.f);
}
}
const uint32 TriCount = static_cast<uint16>(std::min<size_t>(65535, Pos.size() / 4));//vertex count at 4float/vertex
rWriter.Write(TriCount);
rWriter.Align<16>();
rWriter.Write(&Pos[0], 4 * TriCount * sizeof(float));
rWriter.Align<4>();
const size_t PosEnd = rWriter.Pos();
return PosEnd - PosStart;//sizeof(TriCount)+sizeof(Pos[0])*Pos.size();
}
void COCMExporter::SaveInstance(CFileEndianWriter& rWriter, const Export::Object* pInstance, const SOCMeshInfo& rMeshInfo)
{
Vec3 pos(pInstance->pos.x, pInstance->pos.y, pInstance->pos.z);
Quat rot(pInstance->rot.w, pInstance->rot.v.x, pInstance->rot.v.y, pInstance->rot.v.z);
Vec3 scale(pInstance->scale.x, pInstance->scale.y, pInstance->scale.z);
Matrix44 tm = Matrix33::CreateScale(scale) * Matrix34(rot);
tm.SetTranslation(pos);
tm = tm * rMeshInfo.m_OBBMat.GetInverted();
//const uint32 MeshID = pInstance->MeshToUse()->ID();
rWriter.Write(rMeshInfo.m_Offset);
for (size_t a = 0; a < 12; a++)//just savin the 3x4 matrix
{
rWriter.Write(*(reinterpret_cast<float*>(&tm) + a));
}
}
bool COCMExporter::ExportToFile(const char* filename, const Export::IData* pExportData)
{
CLogFile::FormatLine("Exporting OCM file to '%s'", filename);
FILE* pFile = nullptr;
azfopen(&pFile, filename, "wb");
if (!pFile)
{
CLogFile::FormatLine("Error while opening file '%s'!", filename);
assert(pFile);
return false;
}
CFileEndianWriter Writer;
// Write header
const uint32 Version = ~(4u << 24);
const uint32 MeshCount = pExportData->GetObjectCount();
const uint32 InstCount = pExportData->GetObjectCount();
uint32 OffsetInstances = 0;
Writer.Write(Version);
Writer.Write(MeshCount);
Writer.Write(InstCount);
Writer.Write(OffsetInstances);//keep header end aligned to 16byte
tdMeshOffset MeshOffsets;
MeshOffsets.reserve(MeshCount);
size_t Offset = 16;
//std::map<void*,size_t> MeshO
for (size_t a = 0; a < MeshCount; a++)
{
SOCMeshInfo MeshInfo;
MeshInfo.m_MeshHash = pExportData->GetObject(a)->MeshHash();
const tdMeshOffset::iterator it = std::find(MeshOffsets.begin(), MeshOffsets.end(), MeshInfo);
if (it != MeshOffsets.end())
{
MeshInfo = *it;
}
else
{
MeshInfo.m_Offset = Offset;
Offset += SaveMesh(Writer, pExportData->GetObject(a), MeshInfo.m_OBBMat);
}
MeshOffsets.push_back(MeshInfo);
}
OffsetInstances = Offset;
for (size_t a = 0; a < InstCount; a++)
{
SaveInstance(Writer, pExportData->GetObject(a), MeshOffsets[a]);
}
Writer.Seek(4);
Writer.Write(static_cast<uint32>(MeshOffsets.size()));
Writer.Seek(12);
Writer.Write(OffsetInstances);
fwrite(&Writer.Data()[0], 1, Writer.Data().size(), pFile);
fclose(pFile);
return true;
}
const char* COCMExporter::TrimFloat(float fValue) const
{
// Convert a float into a string representation and remove all
// unnecessary zeros and the decimal dot if it is not needed
const int nMaxAccessInTime = 4;
static char ppBufs[nMaxAccessInTime][16];
static int nCurBuf = 0;
if (nCurBuf >= nMaxAccessInTime)
{
nCurBuf = 0;
}
char* pBuf = ppBufs[nCurBuf];
size_t bufSize = sizeof(ppBufs[nCurBuf]);
++nCurBuf;
sprintf_s(pBuf, bufSize, "%f", fValue);
for (int i = strlen(pBuf) - 1; i > 0; --i)
{
if (pBuf[i] == '0')
{
pBuf[i] = 0;
}
else if (pBuf[i] == '.')
{
pBuf[i] = 0;
break;
}
else
{
break;
}
}
return pBuf;
}
void COCMExporter::Release()
{
delete this;
}
+49
View File
@@ -0,0 +1,49 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
// Description : Export geometry OCM file format
#ifndef CRYINCLUDE_EDITOR_EXPORT_OCMEXPORTER_H
#define CRYINCLUDE_EDITOR_EXPORT_OCMEXPORTER_H
#pragma once
#include <IExportManager.h>
class CFileEndianWriter;
struct SOCMeshInfo
{
Matrix44 m_OBBMat;
uint32 m_Offset;
size_t m_MeshHash;
bool operator==(const SOCMeshInfo& rOther) const{return m_MeshHash == rOther.m_MeshHash; }
};
typedef std::vector<SOCMeshInfo> tdMeshOffset;
class COCMExporter
: public IExporter
{
public:
virtual const char* GetExtension() const;
virtual const char* GetShortDescription() const;
virtual bool ExportToFile(const char* filename, const Export::IData* pExportData);
virtual bool ImportFromFile([[maybe_unused]] const char* filename, [[maybe_unused]] Export::IData* pData){return false; };
virtual void Release();
private:
const char* TrimFloat(float fValue) const;
void SaveInstance(CFileEndianWriter& rWriter, const Export::Object* pInstance, const SOCMeshInfo& rMeshInfo);
size_t SaveMesh(CFileEndianWriter& rWriter, const Export::Object* pMesh, Matrix44& rOBBMat);
void Extends(const Matrix44& rTransform, const Export::Object* pMesh, f32& rMinX, f32& rMaxX, f32& rMinY, f32& rMaxY, f32& rMinZ, f32& rMaxZ) const;
Matrix44 CalcOBB(const Export::Object* pMesh);
};
#endif // CRYINCLUDE_EDITOR_EXPORT_OCMEXPORTER_H