<commit_before>#include "render_scene.h"
#include "core/array.h"
#include "core/crc32.h"
#include "core/event_manager.h"
#include "core/FS/file_system.h"
#include "core/FS/ifile.h"
#include "core/iserializer.h"
#include "core/log.h"
#include "core/resource_manager.h"
#include "core/resource_manager_base.h"
#include "core/timer.h"
#include "engine/engine.h"
#include "graphics/geometry.h"
#include "graphics/irender_device.h"
#include "graphics/material.h"
#include "graphics/model.h"
#include "graphics/model_instance.h"
#include "graphics/pipeline.h"
#include "graphics/renderer.h"
#include "graphics/texture.h"
#include "universe/component_event.h"
#include "universe/entity_moved_event.h"
#include "universe/universe.h"


namespace Lumix
{

	static const uint32_t RENDERABLE_HASH = crc32("renderable");
	static const uint32_t LIGHT_HASH = crc32("light");
	static const uint32_t CAMERA_HASH = crc32("camera");
	static const uint32_t TERRAIN_HASH = crc32("terrain");

	struct Terrain
	{
		Terrain()
			: m_mesh(NULL)
			, m_material(NULL)
		{}

		~Terrain()
		{
			LUMIX_DELETE(m_mesh);
			if (m_material)
			{
				m_material->getResourceManager().get(ResourceManager::MATERIAL)->unload(*m_material);
			}
			if (m_heightmap)
			{
				m_heightmap->getResourceManager().get(ResourceManager::TEXTURE)->unload(*m_heightmap);
				m_heightmap->getObserverCb().unbind<Terrain, &Terrain::heightmapLoaded>(this);
			}
		}

		void generateGeometry()
		{
			LUMIX_DELETE(m_mesh);
			m_mesh = NULL;
			struct Vertex
			{
				Vec3 pos;
				float u, v;
				float u2, v2;
				Vec3 normal;
			};
			m_width = m_heightmap->getWidth();
			m_height = m_heightmap->getHeight();
			Array<Vertex> points;
			points.resize(m_width * m_height * 4);
			Array<int32_t> indices;
			indices.resize((m_width - 1) * (m_height - 1) * 6);
			int indices_offset = 0;
			const uint8_t* data = m_heightmap->getData();
			int bytes_per_pixel = m_heightmap->getBytesPerPixel();
			for (int j = 0; j < m_height - 1; ++j)
			{
				for (int i = 0; i < m_width - 1; ++i)
				{
					int idx = 4 * (i + j * m_width);
					int data_idx = i + j * m_width;
					points[idx].pos.set((float)(i) / 5, data[data_idx * bytes_per_pixel] / 20.0f - 255 / 20.0f, (float)(j) / 5);
					points[idx].u2 = 0;
					points[idx].v2 = 0;
					points[idx].u = i / (float)m_width;
					points[idx].v = j / (float)m_height;
					points[idx+1].pos.set((float)(i+1) / 5, data[(data_idx + 1)* bytes_per_pixel] / 20.0f - 255 / 20.0f, (float)(j) / 5);
					points[idx+1].u2 = 1;
					points[idx+1].v2 = 0;
					points[idx+1].u = (i+1) / (float)m_width;
					points[idx+1].v = j / (float)m_height;
					points[idx+2].pos.set((float)(i+1) / 5, data[(data_idx + 1 + m_width)* bytes_per_pixel] / 20.0f - 255 / 20.0f, (float)(j+1) / 5);
					points[idx+2].u2 = 1;
					points[idx+2].v2 = 1;
					points[idx+2].u = (i+1) / (float)m_width;
					points[idx+2].v = (j+1) / (float)m_height;
					points[idx+3].pos.set((float)(i) / 5, data[(data_idx + m_width) * bytes_per_pixel] / 20.0f - 255 / 20.0f, (float)(j+1) / 5);
					points[idx+3].u2 = 0;
					points[idx+3].v2 = 1;
					points[idx+3].u = i / (float)m_width;
					points[idx+3].v = (j+1) / (float)m_height;
					
					indices[indices_offset] = idx;
					indices[indices_offset + 1] = idx + 3;
					indices[indices_offset + 2] = idx + 2;
					indices[indices_offset + 3] = idx;
					indices[indices_offset + 4] = idx + 2;
					indices[indices_offset + 5] = idx + 1;
					indices_offset += 6;
				}
			}
			/*for (int j = 1; j < m_height - 1; ++j)
			{
				for (int i = 1; i < m_width - 1; ++i)
				{
					int idx = i + j * m_width;
					Vec3 n = crossProduct(points[idx + 1].pos - points[idx - 1].pos, points[idx - m_width].pos - points[idx + m_width].pos);
					n.normalize();
					points[idx].normal = n;
				}
			}*/
			VertexDef vertex_def;
			vertex_def.parse("ptf2n", 5);
			m_geometry.copy((const uint8_t*)&points[0], sizeof(points[0]) * points.size(), indices, vertex_def);
			m_mesh = LUMIX_NEW(Mesh)(m_material, 0, indices.size(), "terrain");
		}

		void heightmapLoaded(Resource::State, Resource::State new_state)
		{
			if (new_state == Resource::State::READY)
			{
				generateGeometry();
			}
		}<commit_msg>normals in terrain fixed<commit_after>#include "render_scene.h"
#include "core/array.h"
#include "core/crc32.h"
#include "core/event_manager.h"
#include "core/FS/file_system.h"
#include "core/FS/ifile.h"
#include "core/iserializer.h"
#include "core/log.h"
#include "core/resource_manager.h"
#include "core/resource_manager_base.h"
#include "core/timer.h"
#include "engine/engine.h"
#include "graphics/geometry.h"
#include "graphics/irender_device.h"
#include "graphics/material.h"
#include "graphics/model.h"
#include "graphics/model_instance.h"
#include "graphics/pipeline.h"
#include "graphics/renderer.h"
#include "graphics/texture.h"
#include "universe/component_event.h"
#include "universe/entity_moved_event.h"
#include "universe/universe.h"


namespace Lumix
{

	static const uint32_t RENDERABLE_HASH = crc32("renderable");
	static const uint32_t LIGHT_HASH = crc32("light");
	static const uint32_t CAMERA_HASH = crc32("camera");
	static const uint32_t TERRAIN_HASH = crc32("terrain");

	struct Terrain
	{
		Terrain()
			: m_mesh(NULL)
			, m_material(NULL)
		{}

		~Terrain()
		{
			LUMIX_DELETE(m_mesh);
			if (m_material)
			{
				m_material->getResourceManager().get(ResourceManager::MATERIAL)->unload(*m_material);
			}
			if (m_heightmap)
			{
				m_heightmap->getResourceManager().get(ResourceManager::TEXTURE)->unload(*m_heightmap);
				m_heightmap->getObserverCb().unbind<Terrain, &Terrain::heightmapLoaded>(this);
			}
		}

		void generateGeometry()
		{
			LUMIX_DELETE(m_mesh);
			m_mesh = NULL;
			struct Vertex
			{
				Vec3 pos;
				float u, v;
				float u2, v2;
				Vec3 normal;
			};
			m_width = m_heightmap->getWidth();
			m_height = m_heightmap->getHeight();
			Array<Vertex> points;
			points.resize(m_width * m_height * 4);
			Array<int32_t> indices;
			indices.resize((m_width - 1) * (m_height - 1) * 6);
			int indices_offset = 0;
			const uint8_t* data = m_heightmap->getData();
			int bytes_per_pixel = m_heightmap->getBytesPerPixel();
			for (int j = 0; j < m_height - 1; ++j)
			{
				for (int i = 0; i < m_width - 1; ++i)
				{
					int idx = 4 * (i + j * m_width);
					int data_idx = i + j * m_width;
					points[idx].pos.set((float)(i) / 5, data[data_idx * bytes_per_pixel] / 20.0f - 255 / 20.0f, (float)(j) / 5);
					points[idx].u2 = 0;
					points[idx].v2 = 0;
					points[idx].u = i / (float)m_width;
					points[idx].v = j / (float)m_height;
					points[idx+1].pos.set((float)(i+1) / 5, data[(data_idx + 1)* bytes_per_pixel] / 20.0f - 255 / 20.0f, (float)(j) / 5);
					points[idx+1].u2 = 1;
					points[idx+1].v2 = 0;
					points[idx+1].u = (i+1) / (float)m_width;
					points[idx+1].v = j / (float)m_height;
					points[idx+2].pos.set((float)(i+1) / 5, data[(data_idx + 1 + m_width)* bytes_per_pixel] / 20.0f - 255 / 20.0f, (float)(j+1) / 5);
					points[idx+2].u2 = 1;
					points[idx+2].v2 = 1;
					points[idx+2].u = (i+1) / (float)m_width;
					points[idx+2].v = (j+1) / (float)m_height;
					points[idx+3].pos.set((float)(i) / 5, data[(data_idx + m_width) * bytes_per_pixel] / 20.0f - 255 / 20.0f, (float)(j+1) / 5);
					points[idx+3].u2 = 0;
					points[idx+3].v2 = 1;
					points[idx+3].u = i / (float)m_width;
					points[idx+3].v = (j+1) / (float)m_height;
					
					indices[indices_offset] = idx;
					indices[indices_offset + 1] = idx + 3;
					indices[indices_offset + 2] = idx + 2;
					indices[indices_offset + 3] = idx;
					indices[indices_offset + 4] = idx + 2;
					indices[indices_offset + 5] = idx + 1;
					indices_offset += 6;
				}
			}
			for (int j = 1; j < m_height - 1; ++j)
			{
				for (int i = 1; i < m_width - 1; ++i)
				{
					int idx = 4 * (i + j * m_width);
					for (int k = 0; k < 4; ++k)
					{
						Vec3 n = crossProduct(points[idx + 4].pos - points[idx - 4].pos, points[idx - m_width * 4].pos - points[idx + m_width * 4].pos);
						n.normalize();
						points[idx].normal = n;
						++idx;
					}
				}
			}
			VertexDef vertex_def;
			vertex_def.parse("ptf2n", 5);
			m_geometry.copy((const uint8_t*)&points[0], sizeof(points[0]) * points.size(), indices, vertex_def);
			m_mesh = LUMIX_NEW(Mesh)(m_material, 0, indices.size(), "terrain");
		}

		void heightmapLoaded(Resource::State, Resource::State new_state)
		{
			if (new_state == Resource::State::READY)
			{
				generateGeometry();
			}
		}
{'fraction_non_alphanumeric': 0.17432273262661954, 'fraction_numerical': 0.0342756183745583, 'mean_word_length': 3.2927199191102123, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5976130', 'n_tokens_mistral': 4118, 'n_tokens_neox': 3373, 'n_words': 640}