2#pragma warning(disable: 4324)
3#pragma warning(disable: 4201)
4#pragma warning(disable: 4310)
5#pragma warning(disable: 4458)
8#include "RadialLogComponent.h"
10#include "EntityStore.h"
12#include "Components/Core/MeshComponent.h"
13#include "Components/Core/MeshRenderComponent.h"
14#include "Components/Core/SubMeshRenderComponent.h"
15#include "Components/Core/TransformComponent.h"
17#include "Resources/MaterialManager.h"
18#include "Resources/DefaultMaterial.h"
19#include "Resources/MeshManager.h"
27 void RadialLogComponent::registerType()
45 Method(
Name(
"initialize"), &RadialLogComponent::initialize),
46 Method(
Name(
"update"), &RadialLogComponent::update),
48 TypeDatabase::createType<RadialLogComponent>()
51 .setBase<DynamicComponent>();
53 RadialLogComponent::RadialLogComponent():
57 void RadialLogComponent::initialize(Context *set_context)
59 context = set_context;
60 auto material = context->materialManager->getDefaultMaterial();
61 instance = context->materialInstanceManager->createMaterialInstance(material);
62 instance->setVariant(
"EnableLighting",
false);
63 instance->setVariant(
"VertexColor",
true);
64 instance->setVariant(
"LightModel",
"BaseColor");
65 instance->setVariant(
"Textured",
false);
66 instance->setOption(
"CullMode",
"None");
67 instance->setVec3Property(DefaultMaterial::EmissiveColor, glm::vec3(0.0));
70 void RadialLogComponent::update()
72 if (!normalize_range && (lr_min == r_min) && (lr_max == r_max))
return;
74 if (!radiuses || !radiuses.size() || !indexes || !indexes.size() || !gradient || !gradient.size())
return;
78 auto entity = getContainer();
80 if (normalize_range) {
81 normalize_range =
false;
82 float r_a = 999999999.0f;
83 float r_b = -999999999.0f;
84 for (
float tmp : radiuses) {
85 if (tmp < 0.0f)
continue;
86 r_a = glm::min(r_a, tmp);
87 r_b = glm::max(r_b, tmp);
93 const size_t sample_count = indexes.size();
94 const size_t sectors = radiuses.size() / sample_count;
96 const size_t indexes_per_sample = (2 * sectors + 2 + 1);
97 const size_t vertex_count = sample_count * sectors;
98 const size_t max_index_count = sample_count * indexes_per_sample;
101 std::vector<unsigned int> indexBuffer(max_index_count);
103 for (uint32_t s = 0; s < (uint32_t)(sample_count - 1); s++) {
104 for (uint32_t r = 0; r < (uint32_t)sectors; r++) {
105 indexBuffer[i++] = (s * (uint32_t)sectors) + r;
106 indexBuffer[i++] = ((s + 1) * (uint32_t)sectors) + r;
109 indexBuffer[i++] = (s * (uint32_t)sectors);
110 indexBuffer[i++] = ((s + 1) * (uint32_t)sectors);
112 indexBuffer[i++] = ((s + 1) * (uint32_t)sectors);
116 MeshComponent* meshComp = entity->getComponent<MeshComponent>();
117 auto mesh = context->meshManager->createLocked();
118 meshComp->meshHandle = mesh.getHandle();
119 auto meshRenderComp = entity->getComponent<MeshRenderComponent>();
120 if (meshRenderComp) meshRenderComp->material = instance;
122 std::vector<glm::vec3> vertexBuffer(vertex_count);
123 std::vector<glm::vec4> colorsVector(vertex_count);
124 unsigned int idx = 0;
125 for (
size_t s = 0; s < sample_count; s++) {
127 const glm::vec3 p = positions[s];
129 for (
size_t r = 0; r < sectors; r++) {
131 float ra = radiuses[r + s * sectors];
133 float rad = glm::half_pi<float>() - 2.0f * (float(r) / sectors) * glm::pi<float>();
134 glm::vec3 xz = glm::vec3(ra * cosf(rad), 0, ra * sinf(rad));
135 glm::vec3 rotated = glm::rotateZ(glm::rotateX(xz, -inclinations[s]), -azimuths[s]);
137 vertexBuffer[idx] = p + rotated;
139 if (colors && colors.size()) {
143 float col = glm::clamp((ra - r_min) / (r_max - r_min), 0.0f, 1.0f);
144 size_t gs = gradient.size() - 1;
145 float gsc = col * gs;
146 size_t ia = glm::clamp<size_t>((
size_t)glm::floor(gsc), 0, gs);
147 size_t ib = glm::clamp(ia + 1, (
size_t)0, gs);
148 glm::vec3 a = gradient[ia];
149 glm::vec3 b = gradient[ib];
150 float t = glm::clamp((gsc - (
float)ia), 0.0f, 1.0f);
151 color = glm::vec4(glm::mix(a, b, t), 1.0);
153 colorsVector[idx] = color;
158 size_t index_count = (sample_count - 1) * indexes_per_sample;
159 mesh->primitiveType = PrimitiveType::EPrimitiveType::TriangleStrip;
160 mesh->setPositions(vertexBuffer.data(), vertexBuffer.data() + vertexBuffer.size());
161 mesh->setColors(colorsVector);
162 mesh->setIndexData(indexBuffer.data(), index_count);
163 meshComp->setChanged();
170 void RadialLogComponent::generateHighSide() {
171 const size_t sample_count = indexes.size();
172 const size_t sectors = radiuses.size() / sample_count;
174 if (highSide ==
nullptr) {
175 auto entity = getContainer();
176 highSide = context->store->createChildEntity(
"MeshPart", entity,
"RadialLogHighSide");
178 MeshComponent* meshComp = highSide->getComponent<MeshComponent>();
179 auto mesh = context->meshManager->createLocked();
180 meshComp->meshHandle = mesh.getHandle();
181 auto meshRenderComp = meshComp->getComponent<MeshRenderComponent>();
182 if (meshRenderComp) meshRenderComp->material = instance;
184 size_t vertex_count = sample_count * 2;
186 std::vector<glm::vec3> vertexBuffer(vertex_count);
187 std::vector<glm::vec4> colors(vertex_count);
188 unsigned int idx = 0;
189 for (
size_t s = 0; s < sample_count; s++) {
190 size_t r = high_side_index;
191 size_t r_idx = s * sectors + r;
193 for (
size_t j = 0; j < 2; j++) {
195 float ra = radiuses[r_idx] + j * high_side_size;
197 float rad = glm::half_pi<float>() - 2.0f * (float(r) / sectors) * glm::pi<float>();
198 glm::vec3 xz = glm::vec3(ra * cosf(rad), 0, ra * sinf(rad));
199 glm::vec3 rotated = glm::rotateZ(glm::rotateX(xz, -inclinations[s]), -azimuths[s]);
201 vertexBuffer[idx] = positions[md_idx] + rotated;
202 colors[idx] = high_side_color;
207 mesh->primitiveType = PrimitiveType::EPrimitiveType::TriangleStrip;
208 mesh->setPositions(vertexBuffer.data(), vertexBuffer.data() + vertexBuffer.size());
209 mesh->setColors(colors);
210 meshComp->setChanged();
Field definition describing a single data member of a data structure.
static FieldWrapper< Field, FieldType > create(const Name &name, FieldType ClassType::*field)
Creates a new field instance, returning a wrapper for type safe continuation style setup.
Simple method definition.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
Contains reflection support.
void setChanged(Cogs::Core::Context *context, Cogs::ComponentModel::Component *component, Reflection::FieldId fieldId)
Must be Called after changing a Component field. Mark field changed. Request engine update.
float r_max
Manual max radius for gradient.
glm::vec4 high_side_color
Color for drawing high side indicator.
uint32_t high_side_index
Index of sector to use for finding radius.
BufferView< glm::vec3 > positions
Center position for each sample.
BufferView< float > azimuths
Clockwise rotation from grid north in radians, per sample.
bool normalize_range
Automatically use min/max radius (from buffer) with gradient.
BufferView< float > radiuses
One radius per sector (sectors = radiuses/samples).
BufferView< glm::vec4 > colors
One color per radius value, only used if set.
BufferView< float > indexes
Measured depth per sample.
float high_side_size
Height of high side indicator.
BufferView< glm::vec3 > gradient
Color gradient.
BufferView< float > inclinations
Positive values interpreted as down, per sample.
float r_min
Manual min radius for gradient.
Represents an unique name.