9 #include <argos3/core/utility/math/quaternion.h>
10 #include <argos3/core/utility/logging/argos_log.h>
11 #include <argos3/core/simulator/simulator.h>
12 #include <argos3/core/simulator/space/space.h>
16 static const Real MOVE_GAIN = 0.005 /
Exp(0.02);
17 static const Real ROTATE_GAIN = 0.01 /
Exp(-0.02);
18 static const Real FOCAL_LENGTH_GAIN = 0.0075;
19 static const Real FOCAL_LENGTH_OFFSET = 0.0575;
36 if(cForward.
GetX() != 0 || cForward.
GetY() != 0) {
43 LOGERR <<
"[WARNING] The given camera position is ambiguous, "
44 <<
"and a standard attitude has been used to calculate it. "
45 <<
"Consider specifying the \"up\" vector in the .argos file "
46 <<
"for more precise placement."
61 GetNodeAttributeOrDefault<Real>(t_tree,
"lens_focal_length", fValue, 20.0f);
70 YFieldOfView =
ToDegrees(2.0f *
ATan2(0.027f * 0.5f, LensFocalLength));
77 m_bEnableTimeline(false),
78 m_bHasTimeline(false),
87 un_index < m_arrPlacements.size();
90 cAngle *=
static_cast<Real>(un_index);
91 m_arrPlacements[un_index].Position =
93 m_arrPlacements[un_index].Position.RotateZ(cAngle);
94 m_arrPlacements[un_index].Position +=
96 m_arrPlacements[un_index].Target = cArenaCenter;
97 m_arrPlacements[un_index].Target.SetZ(0);
100 m_arrPlacements[un_index].LensFocalLength =
101 (FOCAL_LENGTH_GAIN *
Cos(4.0 * cAngle) + FOCAL_LENGTH_OFFSET);
102 m_arrPlacements[un_index].CalculateYFieldOfView();
121 for(itPlacement = itPlacement.begin(&tPlacementsNode);
122 itPlacement != itPlacement.end();
126 if(unIndex < m_arrPlacements.size()) {
127 m_arrPlacements[unIndex].Init(*itPlacement);
136 m_bHasTimeline =
true;
143 UInt32 unKeyframeStep = 0;
144 UInt32 unKeyframePlacement = 0;
145 for(itTimelineElement = itTimelineElement.begin(&tTimelineNode);
146 itTimelineElement != itTimelineElement.end();
147 ++itTimelineElement) {
149 if(itTimelineElement->Value() ==
"keyframe") {
152 if(unKeyframeStep < unLastStep) {
155 if(m_unLoop && unKeyframeStep > m_unLoop) {
159 unLastStep = unKeyframeStep;
160 m_vecKeyframes.emplace_back(unKeyframeStep,
165 else if(itTimelineElement->Value() ==
"interpolate") {
166 if(!m_vecKeyframes.empty()) {
167 m_vecKeyframes.back().InterpolateToNext =
true;
185 m_bEnableTimeline =
true;
200 gluLookAt(cPosition.
GetX(),
216 m_bEnableTimeline =
false;
218 Real fRotationSensitivity =
222 CRadians(-fRotationSensitivity * c_delta.x()));
253 cNewUp *=
Cos(c_up_down);
254 cNewUp += cForward *
Sin(c_up_down);
265 if(cForward.
GetZ() < 0.0f) {
296 if(cForward.
GetX() != 0 || cForward.
GetY() != 0) {
322 cNewForwardXY *=
Cos(c_left_right);
323 cNewForwardXY += cLeftXY *
Sin(c_left_right);
334 cNewForwardXY *= cForwardXYLength;
336 cForward.
SetX(cNewForwardXY.
GetX());
337 cForward.
SetY(cNewForwardXY.
GetY());
346 cLeft *=
Cos(c_left_right);
347 cLeft -= cForwardXY *
Sin(c_left_right);
355 m_sActivePlacement.
Target += cForward;
365 m_bEnableTimeline =
false;
375 cForward * (fMotionSensitivity * n_forwards_backwards) +
376 cLeft * (fMotionSensitivity * n_sideways) +
377 cUp * (fMotionSensitivity * n_up_down);
379 m_sActivePlacement.
Target += cForward;
387 Real f_time_fraction) {
388 const SPlacement& sStart = m_arrPlacements[un_start_placement];
389 const SPlacement& sEnd = m_arrPlacements[un_end_placement];
392 m_sActivePlacement.
Position *= f_time_fraction;
396 m_sActivePlacement.
Target *= f_time_fraction;
399 m_sActivePlacement.
Up = (sEnd.
Up - sStart.
Up);
400 m_sActivePlacement.
Up *= f_time_fraction;
401 m_sActivePlacement.
Up += sStart.
Up;
414 if(!m_bEnableTimeline)
417 std::vector<SKeyframe>::const_iterator itCurrent =
418 std::cbegin(m_vecKeyframes);
419 std::vector<SKeyframe>::const_iterator itNext =
420 std::cbegin(m_vecKeyframes);
421 if(itCurrent == std::cend(m_vecKeyframes)) {
432 while(itNext != std::cend(m_vecKeyframes) &&
433 itNext->Step < unStep) {
434 itCurrent = itNext++;
437 if(itCurrent == itNext) {
441 else if(itNext == std::cend(m_vecKeyframes)) {
442 if(itCurrent->Step == unStep - 1) {
448 if(itCurrent->InterpolateToNext) {
449 Real fSegmentTimeFraction =
450 (unStep - itCurrent->Step) /
451 static_cast<Real>(itNext->Step - itCurrent->Step);
453 itNext->PlacementIndex,
454 fSegmentTimeFraction);
457 if(itCurrent->Step == unStep - 1) {
464 if(itCurrent == itNext) {
467 itCurrent = std::prev(std::cend(m_vecKeyframes));
468 if(itCurrent == itNext) {
472 m_bEnableTimeline =
false;
474 else if(itCurrent->InterpolateToNext) {
475 Real fSegmentTimeFraction =
476 (m_unLoop - itCurrent->Step + unStep) /
477 static_cast<Real>(m_unLoop - itCurrent->Step + itNext->Step);
479 itNext->PlacementIndex,
480 fSegmentTimeFraction);
486 else if(itNext == std::cend(m_vecKeyframes)) {
487 itNext = std::cbegin(m_vecKeyframes);
488 if(itCurrent == itNext) {
492 m_bEnableTimeline =
false;
494 else if(itCurrent->InterpolateToNext) {
495 Real fSegmentTimeFraction =
496 (unStep - itCurrent->Step) /
497 static_cast<Real>(m_unLoop - itCurrent->Step + itNext->Step);
499 itNext->PlacementIndex,
500 fSegmentTimeFraction);
507 if(itCurrent->InterpolateToNext) {
508 Real fSegmentTimeFraction =
509 (unStep - itCurrent->Step) /
510 static_cast<Real>(itNext->Step - itCurrent->Step);
512 itNext->PlacementIndex,
513 fSegmentTimeFraction);
#define THROW_ARGOSEXCEPTION_NESTED(message, nested)
This macro throws an ARGoS exception with the passed message and nesting the passed exception.
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
signed int SInt32
32-bit signed integer.
unsigned int UInt32
32-bit unsigned integer.
float Real
Collects all ARGoS code.
The namespace containing all the ARGoS related code.
ticpp::Iterator< ticpp::Element > TConfigurationNodeIterator
The iterator for the ARGoS configuration XML node.
CARGoSLog LOGERR(std::cerr, SLogColor(ARGOS_LOG_ATTRIBUTE_BRIGHT, ARGOS_LOG_COLOR_RED))
TConfigurationNode & GetNode(TConfigurationNode &t_node, const std::string &str_tag)
Given a tree root node, returns the first of its child nodes with the wanted name.
Real Cos(const CRadians &c_radians)
Computes the cosine of the passed value in radians.
bool NodeAttributeExists(TConfigurationNode &t_node, const std::string &str_attribute)
Returns true if the specified attribute of a node exists.
void GetNodeAttributeOrDefault(TConfigurationNode &t_node, const std::string &str_attribute, T &t_buffer, const T &t_default)
Returns the value of a node's attribute, or the passed default value.
CDegrees ToDegrees(const CRadians &c_radians)
Converts CRadians to CDegrees.
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
bool NodeExists(TConfigurationNode &t_node, const std::string &str_tag)
Given a tree root node, returns true if one of its child nodes has the wanted name.
Real Sin(const CRadians &c_radians)
Computes the sine of the passed value in radians.
CRadians ATan2(const Real f_y, const Real f_x)
Computes the arctangent of the passed values.
void GetNodeAttribute(TConfigurationNode &t_node, const std::string &str_attribute, T &t_buffer)
Returns the value of a node's attribute.
CSpace & GetSpace() const
Returns a reference to the simulated space.
static CSimulator & GetInstance()
Returns the instance to the CSimulator class.
UInt32 GetSimulationClock() const
Returns the current value of the simulation clock.
const CVector3 & GetArenaSize() const
Returns the arena size.
const CVector3 & GetArenaCenter() const
Returns the arena center.
The exception that wraps all errors in ARGoS.
It defines the basic type CRadians, used to store an angle value in radians.
static const CRadians PI_OVER_TWO
Set to PI / 2.
static const CRadians PI_OVER_SIX
Set to PI / 6.
static const CRadians ZERO
Set to zero radians.
Real GetY() const
Returns the y coordinate of this vector.
CVector2 & Perpendicularize()
Transforms this vector into its ortogonal.
Real GetX() const
Returns the x coordinate of this vector.
Real Length() const
Returns the length of this vector.
static const CVector3 Y
The y axis.
CVector3 & CrossProduct(const CVector3 &c_vector3)
Calculates the cross product between this vector and the passed one.
void SetY(const Real f_y)
Sets the y coordinate of this vector.
Real GetX() const
Returns the x coordinate of this vector.
void SetX(const Real f_x)
Sets the x coordinate of this vector.
CVector3 & Normalize()
Normalizes this vector.
void Set(const Real f_x, const Real f_y, const Real f_z)
Sets the vector contents from Cartesian coordinates.
void SetZ(const Real f_z)
Sets the z coordinate of this vector.
static const CVector3 X
The x axis.
Real GetY() const
Returns the y coordinate of this vector.
static const CVector3 Z
The z axis.
Real GetZ() const
Returns the z coordinate of this vector.
CRadians GetAngleWith(const CVector3 &c_other)
Returns the angle between this vector and the passed vector.
void SetActivePlacement(UInt32 n_index)
void Interpolate(UInt32 un_start_placement, UInt32 un_end_placement, Real f_time_fraction)
void Move(SInt32 n_forwards_backwards, SInt32 n_sideways, SInt32 n_up_down)
void Init(TConfigurationNode &t_tree)
void Rotate(const QPoint &c_delta)
CVector3 Up
The local Z axis of the camera in the global reference frame.
CVector3 Position
The position of the camera in the global reference frame.
void Init(TConfigurationNode &t_tree)
Initialize from XML.
Real LensFocalLength
The focal length of the lens (if this was a real camera)
CVector3 Target
What we are looking at in the global reference frame.
void CalculateYFieldOfView()
Calculates the value of YFieldOfView.