Generating a dynamic map component via script

I’m working on a project where I want to define the map shape (cube-like map) in JsonFiles and dynamically build the map on the fly. I’m working on acomponent to represent this dynamic map, but I can’t seem to get the top panels to render when I’m in gamemode. There’s a lot of temporary code here but wondering if anyone can spot anything obviously wrong:

MapMeshComponent.h

		class MapMeshComponent
: public AZ::Component
, protected TurnBasedCoreRequestBus::Handler, public IRenderNode
{
public:
AZ_COMPONENT(MapMeshComponent, "{7203383A-E194-4F11-85C9-BBCF99D6CEA3}");
static void Reflect(AZ::ReflectContext* context);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
// interface IRenderNode
virtual void SetMatrix(const Matrix34& mat);
virtual EERType GetRenderNodeType();
virtual const char* GetEntityClassName() const { return "MapMesh"; }
virtual const char* GetName() const;
virtual Vec3 GetPos(bool bWorldOnly = true) const;
virtual void Render(const SRendParams& rParam, const SRenderingPassInfo &passInfo);
virtual IPhysicalEntity* GetPhysics() const { return 0; }
virtual void SetPhysics(IPhysicalEntity*) {}
virtual void SetMaterial(IMaterial* pMat) { m_pMaterial = pMat; }
virtual IMaterial* GetMaterial(Vec3* pHitPos = 0) { return m_pMaterial; }
virtual float GetMaxViewDist();
virtual const AABB GetBBox() const { return m_WSBBox; }
virtual void SetBBox(const AABB& WSBBox) { m_WSBBox = WSBBox; }
virtual void OffsetPosition(const Vec3& delta);
virtual IMaterial* GetMaterialOverride() { return 0; };
virtual void GetMemoryUsage(ICrySizer* pSizer) const;
protected:
IStatObj* GenerateTestMesh();
IStatObj* m_testMesh;
AABB m_WSBBox;
Matrix34 m_mat;
_smart_ptr< IMaterial > m_pMaterial;
////////////////////////////////////////////////////////////////////////
// TurnBasedCoreRequestBus interface implementation
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// AZ::Component interface implementation
void Init() override;
void Activate() override;
void Deactivate() override;
////////////////////////////////////////////////////////////////////////
};

MapMeshComponent.cpp

	IStatObj* MapMeshComponent::GenerateTestMesh()
{
IStatObj* staticObject = gEnv->p3DEngine->CreateStatObj();
IIndexedMesh *idxMesh = staticObject->GetIndexedMesh();
int heights[9] = { 0, 0, 0, 1, 1, 1, 2, 2, 2 };
Map* map = Map::GenerateFromHeightMap(heights, 3, 3);
CMesh* mesh = idxMesh->GetMesh();
mesh->SetVertexCount(9 * 4);
mesh->SetFaceCount(9 * 2);
mesh->SetTexCoordsCount(9 * 4);
//mesh->
Vec3* const vertices = mesh->GetStreamPtr<Vec3>(CMesh::POSITIONS);
Vec3* const normals = mesh->GetStreamPtr<Vec3>(CMesh::NORMALS);
SMeshTexCoord* const uvs = mesh->GetStreamPtr<SMeshTexCoord>(CMesh::TEXCOORDS);
SMeshColor* const colors = mesh->GetStreamPtr<SMeshColor>(CMesh::COLORS_0);
SMeshFace* const faces = mesh->GetStreamPtr<SMeshFace>(CMesh::FACES);
float blockSize = 1.0f;
Vec3 blockForward(0, 0, blockSize * 0.5f);
Vec3 blockLeft(blockSize * 0.5f, 0, 0);
for (int x = 0; x < map->GetWidth(); x++)
{
for (int y = 0; y < map->GetHeight(); y++)
{
Tile tile = map->GetTile(x, y);
if (!tile.visible)
continue;
Vec3 centrePoint(x * blockSize, tile.height * blockSize, y * blockSize);
int vertStartIndex = (x + y*map->GetWidth()) * 4;
int faceStartIndex = (x + y*map->GetWidth()) * 2;
vertices[vertStartIndex+0] = (centrePoint + blockForward + blockLeft);
vertices[vertStartIndex+1] = (centrePoint + blockForward - blockLeft);
vertices[vertStartIndex+2] = (centrePoint - blockForward - blockLeft);
vertices[vertStartIndex+3] = (centrePoint - blockForward + blockLeft);
uvs[vertStartIndex + 0] = SMeshTexCoord(0,0);
uvs[vertStartIndex + 1] = SMeshTexCoord(0,1);
uvs[vertStartIndex + 2] = SMeshTexCoord(1,1);
uvs[vertStartIndex + 3] = SMeshTexCoord(1,0);
//colors[vertStartIndex + 0] = SMeshColor::SMeshColor(tile.r,tile.g,tile.b,tile.a);
//colors[vertStartIndex + 1] = SMeshColor::SMeshColor(tile.r,tile.g,tile.b,tile.a);
//colors[vertStartIndex + 2] = SMeshColor::SMeshColor(tile.r,tile.g,tile.b,tile.a);
//colors[vertStartIndex + 3] = SMeshColor::SMeshColor(tile.r,tile.g,tile.b,tile.a);
normals[vertStartIndex + 0] = Vec3(0, 1, 0);
normals[vertStartIndex + 1] = Vec3(0, 1, 0);
normals[vertStartIndex + 2] = Vec3(0, 1, 0);
normals[vertStartIndex + 3] = Vec3(0, 1, 0);
SMeshFace* const meshface = &faces[faceStartIndex];
meshface->v[0] = vertStartIndex + 2;
meshface->v[1] = vertStartIndex + 1;
meshface->v[2] = vertStartIndex + 0;
meshface->nSubset = 0;
SMeshFace* const meshface2 = &faces[faceStartIndex + 1];
meshface2->v[0] = vertStartIndex + 0;
meshface2->v[1] = vertStartIndex + 3;
meshface2->v[2] = vertStartIndex + 2;
meshface2->nSubset = 0;
//if (includePanels)
//{
//	if (x != 0)
//	{
// HandlePanel(centrePoint + blockForward - blockLeft, centrePoint - blockForward - blockLeft, map.GetTile(x - 1, y).height - tile.height, -blockLeft.normalized, tile.color);
//	}
//
//	if (y != 0)
//	{
// HandlePanel(centrePoint - blockForward - blockLeft, centrePoint - blockForward + blockLeft, map.GetTile(x, y - 1).height - tile.height, -blockForward.normalized, tile.color);
//	}
//}
}
}
idxMesh->CalcBBox();
idxMesh->Optimize();
idxMesh->RestoreFacesFromIndices();
staticObject->SetFlags(STATIC_OBJECT_GENERATED | STATIC_OBJECT_DYNAMIC);
staticObject->Invalidate(true);
CryLog("Created Test Mesh");
return staticObject;
/*
pEntity->Activate(true);
int slotId = pEntity->SetStatObj(staticObject, -1, true);
pObject->Release();*/
}
void MapMeshComponent::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->Class<MapMeshComponent, AZ::Component>()
->Version(0)
->SerializerForEmptyClass();
if (AZ::EditContext* ec = serialize->GetEditContext())
{
ec->Class<MapMeshComponent>("Map Mesh", "[Description of functionality provided by this System Component]")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "TurnBased") ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game"))
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
;
}
}
}
void MapMeshComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("MapMeshService"));
}
void MapMeshComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("MapMeshService"));
}
void MapMeshComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
(void)required;
}
void MapMeshComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
(void)dependent;
}
void MapMeshComponent::Init()
{
m_testMesh = GenerateTestMesh();
m_testMesh->AddRef();
CryLog("MapMeshComponent.Init()::Completed");
}
void MapMeshComponent::Activate()
{
gEnv->p3DEngine->RegisterEntity((IRenderNode *)this);
CryLog("MapMeshComponent.Activate()::Completed");
}
void MapMeshComponent::Deactivate()
{
gEnv->p3DEngine->UnRegisterEntityDirect((IRenderNode *)this);
CryLog("MapMeshComponent.Deactivate()::Completed");
}
void MapMeshComponent::SetMatrix(const Matrix34& mat)
{
m_mat = mat;
m_WSBBox.SetTransformedAABB(mat, AABB(Vec3(-1, -1, -1), Vec3(1, 1, 1)));
gEnv->p3DEngine->RegisterEntity((IRenderNode *)this);
}
const char* MapMeshComponent::GetName() const
{
return "MapMesh";
}
void MapMeshComponent::Render(const SRendParams& rParam, const SRenderingPassInfo &passInfo)
{
CryLog("MapMeshComponent.Render()::Rendering this frame");
SRendParams tempParams(rParam);
tempParams.pMaterial = m_testMesh->GetMaterial();
tempParams.dwFObjFlags |= FOB_DYNAMIC_OBJECT; // only needed if object moved
tempParams.pMatrix = &m_mat;
m_testMesh->Render(tempParams, passInfo);
}
void MapMeshComponent::OffsetPosition(const Vec3& delta)
{
//if (m_pRNTmpData) m_pRNTmpData->OffsetPosition(delta);
m_WSBBox.Move(delta);
m_mat.SetTranslation(m_mat.GetTranslation() + delta);
//if (m_pRE) m_pRE->m_center += delta;
}
void MapMeshComponent::GetMemoryUsage(ICrySizer* pSizer) const
{
SIZER_COMPONENT_NAME(pSizer, "MapMeshComponent");
pSizer->AddObject(this, sizeof(*this));
}
EERType MapMeshComponent::GetRenderNodeType()
{
return eERType_Dummy_2;
}
float MapMeshComponent::GetMaxViewDist()
{
return 1000.0f;
}
Vec3 MapMeshComponent::GetPos(bool bWorldOnly) const
{
return m_mat.GetTranslation();
}

Hi @vethan, I don’t see an obvious problem at a glance, but I would check to make sure that you have the triangles facing the right way and maybe remove the if (!tile.visible) check until you have the problem sorted out.