Cogs.Core
MarkerPointSetSystem.cpp
1#include "MarkerPointSetSystem.h"
2#include "MarkerPointSetPicker.h"
3#include "Context.h"
4#include "Components/Core/TransformComponent.h"
5#include "Components/Core/MeshComponent.h"
6#include "Components/Core/InstancedMeshRenderComponent.h"
7#include "Scene/RayPick.h"
8#include "Services/DPIService.h"
9#include "Resources/Mesh.h"
10#include "Resources/VertexFormats.h"
11#include "Resources/MeshManager.h"
12#include "Systems/Core/CameraSystem.h"
13#include "Utilities/Math.h"
14
15#include "Rendering/IGraphicsDevice.h"
16#include "Rendering/ICapabilities.h"
17
18#include "Foundation/Logging/Logger.h"
19
20namespace
21{
22 const Cogs::Logging::Log logger = Cogs::Logging::getLogger("MarkerPointSetSystem");
23}
24
26{
28
29 // Initialize material
30 pointMaterial = context->materialManager->loadMaterial("MarkerPointSetMaterial.material");
31 context->materialManager->processLoading();
32
33 Material* mat = pointMaterial.resolve();
34 diffuseColorKey = mat->getVec4Key("diffuseColor");
35 outlineColorKey = mat->getVec4Key("outlineColor");
36 viewPlaneLocalKey = mat->getVec4Key("viewPlaneLocal");
37 viewXLocalKey = mat->getVec4Key("viewXLocal");
38 viewYLocalKey = mat->getVec4Key("viewYLocal");
39 pointSizeKey = mat->getVec2Key("pointSize");
40 outlineRelativeRadiusSquaredKey = mat->getFloatKey("outlineRelativeRadiusSquared");
41 nearDistanceKey = mat->getFloatKey("nearDistance");
42 farDistanceKey = mat->getFloatKey("farDistance");
43}
44
45
47{
49
50 if(pool.size() == 1) {
51 assert(!quad);
52 quad = context->meshManager->create();
53
54 std::array<glm::vec2, 4> vertices = {
55 glm::vec2(-0.5f, -0.5f),
56 glm::vec2(0.5f, -0.5f),
57 glm::vec2(-0.5f, 0.5f),
58 glm::vec2(0.5f, 0.5f),
59 };
60 quad->set(VertexDataType::Positions, VertexFormats::Pos2f, vertices);
61 quad->setBounds(Geometry::BoundingBox{ glm::vec3(-1.f, -1.f, 0.f), glm::vec3(1.f, 1.f, 0.f) });
62 quad->primitiveType = Cogs::PrimitiveType::TriangleStrip;
63
64 assert(!picker);
65 picker = std::make_unique<MarkerPointSetPicker>(this);
66 context->rayPicking->addPickable(picker.get());
67 LOG_DEBUG(logger, "Registered marker point set picker extension");
68 }
69 return componentHandle;
70}
71
73{
75
76 if (pool.size() == 0) {
77 assert(quad);
78 quad = MeshHandle();
79
80 assert(picker);
81 context->rayPicking->removePickable(picker.get());
82 picker.reset();
83
84 LOG_DEBUG(logger, "Last component destroyed, unregistered marker point set picker extension");
85 }
86}
87
89{
90 const CameraData& mainCamData = context->cameraSystem->getMainCameraData();
91 const float dpiScale = context->getDefaultView()->dpiService->getScaleFactor();
92
93 for(MarkerPointSetComponent& comp : pool) {
94
96 if (!trComp) { continue; } // just to avoid crash on ill-defined components
97
98 MarkerPointSetData& data = getData(&comp);
99 if (!data.initialized) {
100 data.materialInstance = context->materialInstanceManager->createMaterialInstance(pointMaterial);
101
102 MeshComponent* meshComp = comp.getComponent<MeshComponent>();
103 meshComp->meshHandle = quad;
104 meshComp->setChanged();
105
107 mshRndComp->unsetRenderFlag(RenderFlags::SelfPickable | RenderFlags::ParentPickable); // Picking is handled by MarkerPointSetPicker
108 mshRndComp->material = data.materialInstance;
109 mshRndComp->setChanged();
110 data.initialized = true;
111 }
112
113 // We use the main cam to determine view-dependent orientation etc. This is usually the camera that is used
114 // for rendering. In VR applications, we have a camera per eye, and what they see have to agree, so by using
115 // the main camera to define orientation (and not the the camera used for rendering) they agree.
116 glm::mat4 viewFromLocal = mainCamData.viewMatrix * context->transformSystem->getLocalToWorld(trComp);
117 data.viewPlaneLocal = glm::vec4(0.f, 0.f, -1.f, 0.f) * viewFromLocal;
118 data.viewXLocal = glm::vec3(1.f, 0.f, 0.f) * glm::mat3(viewFromLocal);
119 data.viewYLocal = glm::vec3(0.f, 1.f, 0.f) * glm::mat3(viewFromLocal);
120 data.materialInstance->setVec4Property(viewPlaneLocalKey, data.viewPlaneLocal);
121 data.materialInstance->setVec4Property(viewXLocalKey, glm::vec4(data.viewXLocal, 1.f));
122 data.materialInstance->setVec4Property(viewYLocalKey, glm::vec4(data.viewYLocal, 1.f));
123
124 // Near and far distances are relative to the main camera (distance from viewPLaneLocal)
125 data.materialInstance->setFloatProperty(nearDistanceKey, comp.nearDistance);
126 data.materialInstance->setFloatProperty(farDistanceKey, comp.farDistance);
127
128 // Calculate the amount of the point radius that is inside the outline.
129 float insideOutlineRatio = glm::clamp(1.f - comp.outline / (0.5f * comp.pointSize), 0.f, 1.f);
130 data.materialInstance->setFloatProperty(outlineRelativeRadiusSquaredKey, 0.5f * 0.5f * insideOutlineRatio * insideOutlineRatio);
131
132 data.materialInstance->setVec4Property(diffuseColorKey, comp.diffuseColor);
133 data.materialInstance->setVec4Property(outlineColorKey, comp.outlineColor);
134 data.materialInstance->options.blendMode = comp.smooth ? BlendMode::Blend : BlendMode::None;
135
136 switch (comp.shape) {
138 data.materialInstance->setVariant("Shape", "ViewAlignedDisc");
139 data.materialInstance->setVec2Property(pointSizeKey, glm::vec2(comp.pointSize)); // Point size is object space units.
140 break;
142 data.materialInstance->setVariant("Shape", "ObjectSpaceFloorDisc");
143 data.materialInstance->setVec2Property(pointSizeKey, glm::vec2(comp.pointSize)); // Point size is object space units.
144 break;
146 data.materialInstance->setVariant("Shape", "FixedScreenSizeDisc");
147 // Point size is pixels, and should be dpi and viewport-scaled.
148 data.materialInstance->setVec2Property(pointSizeKey, glm::vec2(dpiScale * comp.pointSize) / (0.5f * mainCamData.viewportSize));
149 break;
150 default:
151 break;
152 };
153
154 // Point positions changed, update instance mesh with new positions.
155 if (comp.hasFieldChanged(&MarkerPointSetComponent::positions)) {
157 if (!mshRndComp->instanceMesh) {
158 mshRndComp->instanceMesh = context->meshManager->create();
159 }
160 mshRndComp->instanceMesh->clear();
161 mshRndComp->instanceMesh->set(VertexDataType::Positions, VertexFormats::InstancePos3f, comp.positions);
162 }
163
164 }
165}
void setChanged()
Sets the component to the ComponentFlags::Changed state with carry.
Definition: Component.h:202
ComponentType * getComponent() const
Definition: Component.h:159
virtual ComponentHandle createComponent()
Create a new component instance.
Context * context
Pointer to the Context instance the system lives in.
virtual void initialize(Context *context)
Initialize the system.
virtual void destroyComponent(ComponentHandle)
Destroy the component held by the given handle.
void update()
Updates the system state to that of the current frame.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
MaterialInstanceHandle material
Material instance used to render the mesh.
MeshHandle instanceMesh
Mesh containing instancing data.
! Generate a set of points for the given position array.
std::vector< glm::vec3 > positions
Marker points positions.
void initialize(Context *context) override
Initialize the system.
ComponentHandle createComponent() override
void destroyComponent(ComponentHandle componentHandle) override
Contains a handle to a Mesh resource to use when rendering using the MeshRenderComponent.
Definition: MeshComponent.h:15
MeshHandle meshHandle
Handle to a Mesh resource to use when rendering.
Definition: MeshComponent.h:29
constexpr void unsetRenderFlag(RenderFlags flag)
Unset the given flag.
Defines a 4x4 transformation matrix for the entity and a global offset for root entities.
Log implementation class.
Definition: LogManager.h:139
@ ParentPickable
Parent pickable, used by the SceneSystem to toggle child entity pickable on/off.
@ SelfPickable
Self pickable, used by the SceneSystem to toggle entity pickable on/off.
@ Blend
Render with regular alpha blending.
@ None
No blending enabled for opaque shapes, defaults to Blend for transparent shapes.
@ ViewAlignedDisc
Point is a flat disc aligned with the main camera view.
@ ObjectSpaceFloorDisc
Point is a flat disc on the XY-plane, point size is object-space diameter of disc.
@ FixedScreenSizeDisc
Point is a screen-space disc, point size is screen-space diameter of disc, won't work with multiple c...
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180
Handle to a Component instance.
Definition: Component.h:67
Contains data describing a Camera instance and its derived data structured such as matrix data and vi...
Definition: CameraSystem.h:67
Material resources define the how of geometry rendering (the what is defined by Mesh and Texture reso...
Definition: Material.h:82
void set(const VertexDataType::EVertexDataType type, VertexFormatHandle format, Element *begin, Element *end)
Set the data of the vertex stream indexed by type.
Definition: Mesh.h:792
void clear()
Clear all data from the Mesh, returning it to its initial non-indexed state with no streams and no su...
Definition: Mesh.cpp:27
ResourceType * resolve() const
Resolve the handle, returning a pointer to the actual resource.
@ TriangleStrip
Triangle strip.
Definition: Common.h:118