1#include "RiserTensionerComponent.h"
5#include "EntityStore.h"
7#include "Components/Data/TrajectoryComponent.h"
8#include "Components/Geometry/VariableExtrusionComponent.h"
9#include "Components/Appearance/MaterialComponent.h"
11#include "ProfileGenerator.h"
12#include "Utilities/Math.h"
14#include "Foundation/Geometry/Glm.hpp"
15#include "Foundation/Geometry/SampleListGenerator.hpp"
16#include "Foundation/Geometry/PathGenerator.hpp"
21void Cogs::Core::RiserTensionerComponent::registerType()
45 Method(
Name(
"initialize"), &RiserTensionerComponent::initialize),
46 Method(
Name(
"update"), &RiserTensionerComponent::update),
49 DynamicComponent::registerDerivedType<RiserTensionerComponent>().setFields(fields).setMethods(methods);
52void Cogs::Core::RiserTensionerComponent::initialize(Context * context)
54 innerShape = context->store->createChildEntity(
"VariableExtrusionShape", getContainer());
55 outerShape = context->store->createChildEntity(
"VariableExtrusionShape", getContainer());
56 trajectory = context->store->createChildEntity(
"Trajectory", getContainer());
58 innerShape->getComponent<VariableExtrusionComponent>()->trajectory = trajectory;
59 outerShape->getComponent<VariableExtrusionComponent>()->trajectory = trajectory;
62void Cogs::Core::RiserTensionerComponent::update()
64 auto variableExtrusion = getComponent<VariableExtrusionComponent>();
66 assert(variableExtrusion &&
"No variable extrusion available for riser.");
68 if (!variableExtrusion->trajectory)
return;
70 auto mainTrajectory = variableExtrusion->trajectory->getComponent<TrajectoryComponent>();
72 if (!mainTrajectory)
return;
74 if (!this->hasChanged() && !variableExtrusion->hasChanged() && !mainTrajectory->hasChanged()) {
75 if (this->getComponent<MaterialComponent>()->hasChanged()) {
84 const float radiusScale = variableExtrusion->radiusScale;
85 const glm::vec3 scaleVector(radiusScale, radiusScale, 1);
87 float queryDepths [2] = {
92 glm::vec3 positions[2];
93 glm::vec3 directions[2];
95 PathGenerator::generateLinearPath(queryDepths,
97 mainTrajectory->indexes.data(),
98 mainTrajectory->positions.data(),
99 static_cast<int>(mainTrajectory->indexes.size()),
103 const glm::vec3 topTrajectoryPosition = positions[0];
104 const glm::vec3 unscaledTopPosition = topTrajectoryPosition + this->topOffset;
106 const glm::vec3 topPosition = topTrajectoryPosition + (this->topOffset * scaleVector);
107 const glm::vec3 bottomTrajectoryPosition = positions[1];
108 const glm::vec3 bottomDirection = directions[1];
110 glm::vec3 bottomOffset = this->bottomOffset;
111 const glm::quat bottomRotation = getRotation(directions[0], bottomDirection);
112 bottomOffset = bottomRotation * bottomOffset;
113 const glm::vec3 unscaledBottomPosition = bottomTrajectoryPosition + bottomOffset;
114 const glm::vec3 bottomPosition = bottomTrajectoryPosition + (bottomOffset * scaleVector);
116 TrajectoryComponent * trajectory = this->trajectory->getComponent<TrajectoryComponent>();
118 auto innerShape = this->innerShape->getComponent<VariableExtrusionComponent>();
119 auto outerShape = this->outerShape->getComponent<VariableExtrusionComponent>();
121 const float unscaledTensionerLength = glm::length(unscaledTopPosition - unscaledBottomPosition);
122 const float tensionerLength = glm::length(topPosition - bottomPosition);
124 const float scaledLengthRatio = tensionerLength / unscaledTensionerLength;
126 trajectory->positions = { topPosition, bottomPosition };
127 trajectory->indexes = { 0, tensionerLength };
128 trajectory->setChanged();
130 const float cylinderRadius = this->cylinderRadius * radiusScale;
131 const float cylinderInnerRadius = this->cylinderInnerRadius * radiusScale;
133 const float cylinderBaseRadius = this->cylinderBaseRadius * radiusScale;
134 const float cylinderBaseLength = this->cylinderBaseLength * scaledLengthRatio;
136 const float cylinderLength = this->cylinderLength * scaledLengthRatio;
138 const float cylinderHeadRadius = this->cylinderHeadRadius * radiusScale;
139 const float cylinderHeadLength = this->cylinderHeadLength * scaledLengthRatio;
141 const float cylinderHeadStart = cylinderLength - cylinderHeadLength;
143 const float rodRadius = this->rodRadius * radiusScale;
145 std::vector<float> depths;
146 std::vector<glm::vec2> profile;
148 std::vector<float> innerDepths;
149 std::vector<glm::vec2> innerProfile;
151 profile.push_back(glm::vec2(0, 0)); depths.push_back(0);
152 profile.push_back(glm::vec2(cylinderBaseRadius, 0)); depths.push_back(0);
153 profile.push_back(glm::vec2(cylinderBaseRadius, 0)); depths.push_back(cylinderBaseLength);
154 profile.push_back(glm::vec2(cylinderRadius, 0)); depths.push_back(cylinderBaseLength);
156 profile.push_back(glm::vec2(cylinderRadius, 0)); depths.push_back(cylinderHeadStart);
157 profile.push_back(glm::vec2(cylinderHeadRadius, 0)); depths.push_back(cylinderHeadStart);
158 profile.push_back(glm::vec2(cylinderHeadRadius, 0)); depths.push_back(cylinderLength);
159 profile.push_back(glm::vec2(rodRadius, 0)); depths.push_back(cylinderLength);
161 profile.push_back(glm::vec2(rodRadius, 0)); depths.push_back(cylinderHeadStart);
162 profile.push_back(glm::vec2(cylinderInnerRadius, 0)); depths.push_back(cylinderHeadStart);
163 profile.push_back(glm::vec2(cylinderInnerRadius, 0)); depths.push_back(cylinderBaseLength);
164 profile.push_back(glm::vec2(0, 0)); depths.push_back(cylinderBaseLength);
166 outerShape->depths = std::move(depths);
167 outerShape->profile = std::move(profile);
168 outerShape->setChanged();
170 const float rodLength = this->rodLength * scaledLengthRatio;
171 const float rodStart = std::max(tensionerLength - rodLength, cylinderBaseLength);
173 innerProfile.push_back(glm::vec2(0, 0)); innerDepths.push_back(rodStart);
174 innerProfile.push_back(glm::vec2(rodRadius, 0)); innerDepths.push_back(rodStart);
176 innerProfile.push_back(glm::vec2(rodRadius, 0)); innerDepths.push_back(tensionerLength);
177 innerProfile.push_back(glm::vec2(0, 0)); innerDepths.push_back(tensionerLength);
179 innerShape->textureScale = glm::vec2(1.0f, 1.0f / (rodLength));
180 innerShape->textureOffset = glm::vec2(0.0f, -rodStart);
182 innerShape->depths = std::move(innerDepths);
183 innerShape->profile = std::move(innerProfile);
184 innerShape->setChanged();
187void Cogs::Core::RiserTensionerComponent::updateChildren()
189 const auto material = getComponent<MaterialComponent>();
191 const auto outerMaterial = outerShape->getComponent<MaterialComponent>();
192 outerMaterial->diffuseColor = material->diffuseColor;
193 outerMaterial->setChanged();
float cylinderHeadRadius
Radius of the cylinder head.
float cylinderRadius
Radius of the main part of the outer cylinder.
float rodRadius
Radius of the rod.
float startDepth
Start depth along trajectory.
float cylinderHeadLength
Length of the cylinder head part (measured from the end of the cylinder).
glm::vec3 topOffset
Offset of top from trajectory position.
float cylinderBaseRadius
Radius of the cylinder base.
float cylinderInnerRadius
Inner radius of the cylinder.
float cylinderLength
Length of the entire outer cylinder.
EntityPtr rodMaterial
Rod material.
float cylinderBaseLength
Length of the cylinder base part (measured from the start of the cylinder).
float endDepth
End depth along trajectory.
float rodLength
Length of the rod.
glm::vec3 bottomOffset
Offset of bottom from trajectory position.
Field definition describing a single data member of a data structure.
Simple method definition.
Contains geometry calculations and generation.
Contains reflection support.
Represents an unique name.