i have: bool rcMeshLoaderObj::load(){ std::vector<TIPLObject> modelPlacements; std::unordered_map<uint16_t, MeshObject> meshes; if (!ReadMapMeshes("output_new.cadf", modelPlacements, meshes)) { return false; } std::cout << "Readed" << std::endl; for (auto& placement : modelPlacements) { uint16_t modelid = placement.modelid; auto meshIt = meshes.find(modelid); if (meshIt == meshes.end()) {  continue; } MeshObject& mesh = meshIt->second;  // Process spheres for (const auto& sphere : mesh.spheres) {  float x = sphere.center.x, y = sphere.center.y, z = sphere.center.z;  transformVertexToWorld(x, y, z, placement);  addSphere(sphere.radius, 16, 8, x, y, z); } // Process boxes for (const auto& box : mesh.boxes) {  // Define the 8 corners of the box based on min and max  float corners[8][3] = {  {box.min.x, box.min.y, box.min.z},  {box.max.x, box.min.y, box.min.z},  {box.min.x, box.max.y, box.min.z},  {box.max.x, box.max.y, box.min.z},  {box.min.x, box.min.y, box.max.z},  {box.max.x, box.min.y, box.max.z},  {box.min.x, box.max.y, box.max.z},  {box.max.x, box.max.y, box.max.z}  };  // Transform each corner to world space  for (int i = 0; i < 8; ++i)  {  transformVertexToWorld(corners[i][0], corners[i][1], corners[i][2], placement);  }  // Add transformed vertices and store their indices  int v0 = m_vertCount;  for (int i = 0; i < 8; ++i)  {  addVertex(corners[i][0], corners[i][1], corners[i][2]);  }  // Define the 12 triangles (2 per face) using the transformed corners  // Front face (min z)  addTriangle(v0 + 0, v0 + 1, v0 + 2);  addTriangle(v0 + 1, v0 + 3, v0 + 2);  // Back face (max z)  addTriangle(v0 + 4, v0 + 6, v0 + 5);  addTriangle(v0 + 5, v0 + 6, v0 + 7);  // Left face (min x)  addTriangle(v0 + 0, v0 + 2, v0 + 4);  addTriangle(v0 + 2, v0 + 6, v0 + 4);  // Right face (max x)  addTriangle(v0 + 1, v0 + 5, v0 + 3);  addTriangle(v0 + 5, v0 + 7, v0 + 3);  // Top face (max y)  addTriangle(v0 + 2, v0 + 3, v0 + 6);  addTriangle(v0 + 3, v0 + 7, v0 + 6);  // Bottom face (min y)  addTriangle(v0 + 4, v0 + 5, v0 + 0);  addTriangle(v0 + 5, v0 + 1, v0 + 0); } // Process faces for (const auto& face : mesh.faces) {  TColFace transformedFace = face;  //std::cout << "Face before transform: A(" << transformedFace.a.x << ", " << transformedFace.a.y << ", " << transformedFace.a.z << ")" << std::endl;  transformVertexToWorld(transformedFace.a.x, transformedFace.a.y, transformedFace.a.z, placement);  transformVertexToWorld(transformedFace.b.x, transformedFace.b.y, transformedFace.b.z, placement);  transformVertexToWorld(transformedFace.c.x, transformedFace.c.y, transformedFace.c.z, placement);  //std::cout << "Face after transform: A(" << transformedFace.a.x << ", " << transformedFace.a.y << ", " << transformedFace.a.z << ")" << std::endl;  int v0 = m_vertCount;  addVertex(transformedFace.a.x, transformedFace.a.y, transformedFace.a.z);  addVertex(transformedFace.b.x, transformedFace.b.y, transformedFace.b.z);  addVertex(transformedFace.c.x, transformedFace.c.y, transformedFace.c.z);  addTriangle(v0, v0 + 1, v0 + 2); } } return true;} where void rcMeshLoaderObj::addVertex(float x, float y, float z){ m_verts.push_back(x * m_scale); m_verts.push_back(y * m_scale); m_verts.push_back(z * m_scale); m_vertCount++;}void rcMeshLoaderObj::addTriangle(int a, int b, int c){ m_tris.push_back(a); m_tris.push_back(b); m_tris.push_back(c); m_triCount++;}void rcMeshLoaderObj::addBox(float centerX, float centerY, float centerZ, float width, float height, float depth){ float halfWidth = width * 0.5f; float halfHeight = height * 0.5f; float halfDepth = depth * 0.5f; // Add vertices int v0 = m_vertCount; addVertex(centerX - halfWidth, centerY - halfHeight, centerZ - halfDepth); addVertex(centerX + halfWidth, centerY - halfHeight, centerZ - halfDepth); addVertex(centerX + halfWidth, centerY + halfHeight, centerZ - halfDepth); addVertex(centerX - halfWidth, centerY + halfHeight, centerZ - halfDepth); addVertex(centerX - halfWidth, centerY - halfHeight, centerZ + halfDepth); addVertex(centerX + halfWidth, centerY - halfHeight, centerZ + halfDepth); addVertex(centerX + halfWidth, centerY + halfHeight, centerZ + halfDepth); addVertex(centerX - halfWidth, centerY + halfHeight, centerZ + halfDepth); // Add triangles addTriangle(v0, v0 + 1, v0 + 2); addTriangle(v0, v0 + 2, v0 + 3); addTriangle(v0 + 1, v0 + 5, v0 + 6); addTriangle(v0 + 1, v0 + 6, v0 + 2); addTriangle(v0 + 5, v0 + 4, v0 + 7); addTriangle(v0 + 5, v0 + 7, v0 + 6); addTriangle(v0 + 4, v0 + 0, v0 + 3); addTriangle(v0 + 4, v0 + 3, v0 + 7); addTriangle(v0 + 3, v0 + 2, v0 + 6); addTriangle(v0 + 3, v0 + 6, v0 + 7); addTriangle(v0 + 4, v0 + 5, v0 + 1); addTriangle(v0 + 4, v0 + 1, v0 + 0);} void rcMeshLoaderObj::addSphere(float radius, int segments, int rings, float centerX, float centerY, float centerZ){ const static float pi = 3.14159265358979323846; int v0 = m_vertCount; // Add vertices for (int ring = 0; ring <= rings; ++ring) { float theta = ring * pi / rings; float sinTheta = sin(theta); float cosTheta = cos(theta); for (int segment = 0; segment <= segments; ++segment) {  float phi = segment * 2 * pi / segments;  float sinPhi = sin(phi);  float cosPhi = cos(phi);  float x = centerX + radius * sinTheta * cosPhi;  float y = centerY + radius * cosTheta;  float z = centerZ + radius * sinTheta * sinPhi;  addVertex(x, y, z); } } for (int ring = 0; ring < rings; ++ring) { int ringStart = ring * (segments + 1); int nextRingStart = (ring + 1) * (segments + 1); for (int segment = 0; segment < segments; ++segment) {  addTriangle(v0 + ringStart + segment,  v0 + nextRingStart + segment,  v0 + ringStart + segment + 1);  addTriangle(v0 + nextRingStart + segment,  v0 + nextRingStart + segment + 1,  v0 + ringStart + segment + 1); } }} and here how i render it: void OptimizedMeshRenderer::initialize(const rcMeshLoaderObj* mesh, float walkableSlopeAngle, float texScale)  {      // Prepare vertex data      const float* verts = mesh->getVerts();      const int* tris = mesh->getTris();      int ntris = mesh->getTriCount();      const float walkableThr = cosf(walkableSlopeAngle / 180.0f * DU_PI);        vertexData.reserve(ntris * 3 * 9); // 3 vertices per triangle, 9 floats per vertex (3 position, 4 color, 2 uv)        for (int i = 0; i < ntris; ++i) {          float norm[3];          mesh->calculateNormal(i, norm);            unsigned int color;          unsigned char a = (unsigned char)(220 * (2 + norm[0] + norm[1]) / 4);          if (norm[1] < walkableThr)              color = duLerpCol(duRGBA(a, a, a, 255), duRGBA(192, 128, 0, 255), 64);          else              color = duRGBA(a, a, a, 255);            for (int j = 0; j < 3; ++j) {              const float* v = &verts[tris[i * 3 + j] * 3];              vertexData.insert(vertexData.end(), { v[0], v[1], v[2] });              vertexData.insert(vertexData.end(), {                  (color & 0xff) / 255.0f,          // Red                  ((color >> 8) & 0xff) / 255.0f,   // Green                  ((color >> 16) & 0xff) / 255.0f,  // Blue                  ((color >> 24) & 0xff) / 255.0f   // Alpha                  });              vertexData.insert(vertexData.end(), { v[0] * texScale, v[1] * texScale });          }      }        vertexCount = ntris * 3;        glGenVertexArrays(1, &vao);      glGenBuffers(1, &vbo);        glBindVertexArray(vao);      glBindBuffer(GL_ARRAY_BUFFER, vbo);      glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof(float), vertexData.data(), GL_STATIC_DRAW);        // Position attribute      glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)0);      glEnableVertexAttribArray(0);      // Color attribute      glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)(3 * sizeof(float)));      glEnableVertexAttribArray(1);      // Texture coord attribute      glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)(7 * sizeof(float)));      glEnableVertexAttribArray(2);        glBindBuffer(GL_ARRAY_BUFFER, 0);      glBindVertexArray(0);  }    void OptimizedMeshRenderer::render()  {      glBindVertexArray(vao);      glDrawArrays(GL_TRIANGLES, 0, vertexCount);      glBindVertexArray(0);  }    OptimizedMeshRenderer::~OptimizedMeshRenderer()  {      glDeleteVertexArrays(1, &vao);      glDeleteBuffers(1, &vbo);  }   m_chunkyMesh = new rcChunkyTriMesh;   if (!m_chunkyMesh)   {       std::cout << ("buildTiledNavigation: Out of memory 'm_chunkyMesh'.\n");       return false;   }   if (!rcCreateChunkyTriMesh(meshloader->getVerts(), meshloader->getVertCount(),       meshloader->getTris(), meshloader->getTriCount(), 1024, m_chunkyMesh))   {       std::cout << ("buildTiledNavigation: Failed to build chunky mesh.");       return false;   }   const float texScale = 1.0f / (0.3f * 10.0f);   meshRenderer.initialize(meshloader, 45.0f, texScale);. But i want to change color of mesh and get data of it (faces, id etc). So, update OptimizedMeshRenderer