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);. So, i want to change color of mesh in realtime (by id) and get info about it such a number of faces etc. So, remake OptimizedMeshRenderer.