Cogs.Core
RiserFlexJointComponent.cpp
1#include "RiserFlexJointComponent.h"
2
3#include "Context.h"
4#include "Types.h"
5
6#include "Components/Data/TrajectoryComponent.h"
7#include "Components/Geometry/VariableExtrusionComponent.h"
8
9#include "ProfileGenerator.h"
10
11#include "Foundation/Geometry/SampleListGenerator.hpp"
12
13using namespace Cogs::Geometry;
14using namespace Cogs::Reflection;
15
16void Cogs::Core::RiserFlexJointComponent::registerType()
17{
18 Field fields [] = {
21
24
27
30
33
35 };
36
37 Method methods [] = {
38 Method(Name("initialize"), &RiserFlexJointComponent::initialize),
39 Method(Name("update"), &RiserFlexJointComponent::update),
40 };
41
42 DynamicComponent::registerDerivedType<RiserFlexJointComponent>().setFields(fields).setMethods(methods);
43}
44
45void Cogs::Core::RiserFlexJointComponent::initialize(Context * /*context*/)
46{
47}
48
49void Cogs::Core::RiserFlexJointComponent::update()
50{
51 auto variableExtrusion = getComponent<VariableExtrusionComponent>();
52
53 assert(variableExtrusion && "No variable extrusion available for riser.");
54
55 if (!variableExtrusion->trajectory) return;
56
57 auto trajectory = variableExtrusion->trajectory->getComponent<TrajectoryComponent>();
58
59 if (!trajectory) return;
60
61 if (!this->hasChanged() && !variableExtrusion->hasChanged()) {
62 return;
63 }
64
65 std::vector<float> trajectoryDepths;
66
67 SampleListGenerator::generateIndexedSamples(startDepth, endDepth, trajectory->indexes.data(), static_cast<int>(trajectory->indexes.size()), trajectoryDepths);
68
69 if (trajectoryDepths.size() < 2) return;
70
71 if (trajectoryDepths[0] > startDepth || trajectoryDepths[trajectoryDepths.size() - 1] < endDepth) return;
72
73 const float radiusScale = variableExtrusion->radiusScale;
74
75 const float connectorLength = this->connectorLength * radiusScale;
76 const float startConnectorEndDepth = startDepth + connectorLength;
77 const float endConnectorStartDepth = endDepth - connectorLength;
78
79 const float flexLocation = startDepth + this->flexStart;
80 const float flexLength = this->flexLength;
81 const float flexStart = flexLocation - flexLength * 0.5f;
82
83 const float innerRadius = this->innerRadius;
84 const float outerRadius = this->outerRadius;
85 const float connectorRadius = this->connectorRadius;
86
87 const float flexRadius = this->flexOuterRadius;
88 const float innerFlexRadius = this->flexInnerRadius;
89
90 const float flexBulgeLength = flexLength / 3;
91 const float flexBulgeEnd = flexStart + flexBulgeLength;
92
93 std::vector<glm::vec2> profile;
94 std::vector<float> depths;
95
96 if (!this->reverse) {
97 ProfileGenerator::generateConnector(depths, profile, startDepth, startConnectorEndDepth, innerRadius, connectorRadius, outerRadius, startDepth);
98 ProfileGenerator::insertPoints(depths, profile, outerRadius, startConnectorEndDepth, flexStart, trajectoryDepths.cbegin(), trajectoryDepths.cend());
99 ProfileGenerator::generateCurvedProfile(depths, profile, flexStart, flexBulgeEnd, outerRadius, flexRadius);
100
101 // Insert the protrusion of the flex shape
102 profile.push_back(glm::vec2(flexRadius, flexLength)); depths.push_back(flexStart);
103 profile.push_back(glm::vec2(innerFlexRadius, flexLength)); depths.push_back(flexStart);
104 profile.push_back(glm::vec2((innerFlexRadius + outerRadius) / 2, 0)); depths.push_back(flexLocation + flexLength / 6);
105 profile.push_back(glm::vec2(outerRadius, 0)); depths.push_back(flexLocation);
106
107 ProfileGenerator::insertPoints(depths, profile, outerRadius, flexLocation, endConnectorStartDepth, trajectoryDepths.cbegin(), trajectoryDepths.cend());
108 ProfileGenerator::generateConnector(depths, profile, endConnectorStartDepth, endDepth, outerRadius, connectorRadius, innerRadius, endDepth);
109 ProfileGenerator::insertPointsReverse(depths, profile, innerRadius, startDepth, endDepth, trajectoryDepths.cend());
110
111 profile.push_back(glm::vec2(innerRadius, 0)); depths.push_back(startDepth);
112 } else {
113 ProfileGenerator::generateConnector(depths, profile, startDepth, startConnectorEndDepth, innerRadius, connectorRadius, outerRadius, startDepth);
114 ProfileGenerator::insertPoints(depths, profile, outerRadius, startConnectorEndDepth, flexStart, trajectoryDepths.cbegin(), trajectoryDepths.cend());
115
116 profile.push_back(glm::vec2(outerRadius, 0)); depths.push_back(flexStart);
117
118 profile.push_back(glm::vec2(innerFlexRadius, 0)); depths.push_back(flexStart - flexLength * 0.5f);
119 profile.push_back(glm::vec2(innerFlexRadius, -flexLength)); depths.push_back(flexStart);
120
121 profile.push_back(glm::vec2(flexRadius, -flexLength)); depths.push_back(flexStart);
122
123 // Middle of profile
124
125 profile.push_back(glm::vec2(flexRadius, flexLength)); depths.push_back(flexStart + flexLength);
126
127 profile.push_back(glm::vec2(innerFlexRadius, flexLength)); depths.push_back(flexStart + flexLength);
128 profile.push_back(glm::vec2(innerFlexRadius, 0)); depths.push_back(flexStart + flexLength + flexLength * 0.5f);
129
130 profile.push_back(glm::vec2(outerRadius, 0)); depths.push_back(flexStart + flexLength);
131
132 ProfileGenerator::generateConnector(depths, profile, endConnectorStartDepth, endDepth, outerRadius, connectorRadius, innerRadius, endDepth);
133 ProfileGenerator::insertPointsReverse(depths, profile, innerRadius, startDepth, endDepth, trajectoryDepths.cend());
134
135 profile.push_back(glm::vec2(innerRadius, 0)); depths.push_back(startDepth);
136
137 ProfileGenerator::reverseProfile(depths, profile, startDepth, endDepth);
138 }
139
140 variableExtrusion->depths = std::move(depths);
141 variableExtrusion->profile = std::move(profile);
142
143 variableExtrusion->setChanged();
144}
float flexStart
Offset of the start of the flex from the start depth.
float endDepth
End depth along trajectory.
float flexInnerRadius
Inner radius of the flex bulge.
float connectorLength
Radius of the connectors.
float connectorRadius
Length of the connectors.
float flexOuterRadius
Outer radius of the flex bulge.
bool reverse
If the shape should be reversed.
float startDepth
Start depth along trajectory.
float flexLength
Length of the flex section.
float innerRadius
Inner radius of the joint.
float outerRadius
Outer radius of the joint.
Field definition describing a single data member of a data structure.
Definition: Field.h:68
Simple method definition.
Definition: Method.h:72
void reverseProfile(std::vector< float > &depths, std::vector< glm::vec2 > &profile, const float startDepth, const float endDepth)
Reverses the given profile.
Contains geometry calculations and generation.
Contains reflection support.
Definition: Component.h:11
Represents an unique name.
Definition: Name.h:70