You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
5.9 KiB
C++
154 lines
5.9 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
|
|
#include "ResourceCompilerPC_precompiled.h"
|
|
#include "CGFNodeMerger.h"
|
|
#include "CGFContent.h"
|
|
#include "StringHelpers.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CGFNodeMerger::SetupMeshSubsets(CContentCGF* pCGF, CMesh& mesh, CMaterialCGF* pMaterialCGF, string& errorMessage)
|
|
{
|
|
const DynArray<int>& usedMaterialIds = pCGF->GetUsedMaterialIDs();
|
|
|
|
unsigned int i;
|
|
if (mesh.m_subsets.empty())
|
|
{
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Setup mesh subsets.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
mesh.m_subsets.clear();
|
|
for (i = 0; i < usedMaterialIds.size(); i++)
|
|
{
|
|
SMeshSubset meshSubset;
|
|
int nMatID = usedMaterialIds[i];
|
|
meshSubset.nMatID = nMatID;
|
|
meshSubset.nPhysicalizeType = PHYS_GEOM_TYPE_NONE;
|
|
mesh.m_subsets.push_back(meshSubset);
|
|
}
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Setup physicalization type from materials (and autofix matId if needed)
|
|
//////////////////////////////////////////////////////////////////////////
|
|
if (pMaterialCGF)
|
|
{
|
|
for (i = 0; i < mesh.m_subsets.size(); i++)
|
|
{
|
|
SMeshSubset& meshSubset = mesh.m_subsets[i];
|
|
if (pMaterialCGF->subMaterials.size() > 0)
|
|
{
|
|
int id = meshSubset.nMatID;
|
|
if (id >= (int)pMaterialCGF->subMaterials.size())
|
|
{
|
|
// Let's use 3dsMax's approach of handling material ids out of range
|
|
id %= (int)pMaterialCGF->subMaterials.size();
|
|
}
|
|
|
|
if (id >= 0 && pMaterialCGF->subMaterials[id] != NULL)
|
|
{
|
|
meshSubset.nMatID = id;
|
|
meshSubset.nPhysicalizeType = pMaterialCGF->subMaterials[id]->nPhysicalizeType;
|
|
}
|
|
else
|
|
{
|
|
errorMessage = StringHelpers::Format(
|
|
"%s: Submaterial %d is not available for subset %d (%d subsets) in %s",
|
|
__FUNCTION__, meshSubset.nMatID, i, (int)mesh.m_subsets.size(), pCGF->GetFilename());
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
meshSubset.nPhysicalizeType = pMaterialCGF->nPhysicalizeType;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CGFNodeMerger::MergeNodes(CContentCGF* pCGF, std::vector<CNodeCGF*> nodes, string& errorMessage, CMesh* pMergedMesh)
|
|
{
|
|
assert(pMergedMesh);
|
|
|
|
AABB meshBBox;
|
|
meshBBox.Reset();
|
|
for (size_t i = 0; i < nodes.size(); i++)
|
|
{
|
|
CNodeCGF* pNode = nodes[i];
|
|
assert(pNode->pMesh == 0 || pNode->pMesh->m_pPositionsF16 == 0);
|
|
int nOldVerts = pMergedMesh->GetVertexCount();
|
|
if (pMergedMesh->GetVertexCount() == 0)
|
|
{
|
|
pMergedMesh->Copy(*pNode->pMesh);
|
|
}
|
|
else
|
|
{
|
|
const char* const errText = pMergedMesh->Append(*pNode->pMesh);
|
|
if (errText)
|
|
{
|
|
errorMessage = errText;
|
|
return false;
|
|
}
|
|
// Keep color stream in sync size with vertex/normals stream.
|
|
if (pMergedMesh->m_streamSize[CMesh::COLORS][0] > 0 && pMergedMesh->m_streamSize[CMesh::COLORS][0] < pMergedMesh->GetVertexCount())
|
|
{
|
|
int nOldCount = pMergedMesh->m_streamSize[CMesh::COLORS][0];
|
|
pMergedMesh->ReallocStream(CMesh::COLORS, 0, pMergedMesh->GetVertexCount());
|
|
memset(pMergedMesh->m_pColor0 + nOldCount, 255, (pMergedMesh->GetVertexCount() - nOldCount) * sizeof(SMeshColor));
|
|
}
|
|
if (pMergedMesh->m_streamSize[CMesh::COLORS][1] > 0 && pMergedMesh->m_streamSize[CMesh::COLORS][1] < pMergedMesh->GetVertexCount())
|
|
{
|
|
int nOldCount = pMergedMesh->m_streamSize[CMesh::COLORS][1];
|
|
pMergedMesh->ReallocStream(CMesh::COLORS, 1, pMergedMesh->GetVertexCount());
|
|
memset(pMergedMesh->m_pColor1 + nOldCount, 255, (pMergedMesh->GetVertexCount() - nOldCount) * sizeof(SMeshColor));
|
|
}
|
|
}
|
|
|
|
AABB bbox = pNode->pMesh->m_bbox;
|
|
if (!pNode->bIdentityMatrix)
|
|
{
|
|
bbox.SetTransformedAABB(pNode->worldTM, bbox);
|
|
}
|
|
|
|
meshBBox.Add(bbox.min);
|
|
meshBBox.Add(bbox.max);
|
|
pMergedMesh->m_bbox = meshBBox;
|
|
|
|
if (!pNode->bIdentityMatrix)
|
|
{
|
|
// Transform merged mesh into the world space.
|
|
// Only transform newly added vertices.
|
|
for (int j = nOldVerts; j < pMergedMesh->GetVertexCount(); j++)
|
|
{
|
|
pMergedMesh->m_pPositions[j] = pNode->worldTM.TransformPoint(pMergedMesh->m_pPositions[j]);
|
|
pMergedMesh->m_pNorms[j].RotateSafelyBy(pNode->worldTM);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool setupMeshSuccessful = true;
|
|
if (pCGF != NULL)
|
|
{
|
|
if (!SetupMeshSubsets(pCGF, *pMergedMesh, pCGF->GetCommonMaterial(), errorMessage))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
pMergedMesh->RecomputeTexMappingDensity();
|
|
|
|
return setupMeshSuccessful;
|
|
}
|