Skip to content

Commit

Permalink
Add missing files
Browse files Browse the repository at this point in the history
  • Loading branch information
gwaldron committed Nov 1, 2024
1 parent 11aceba commit a534e94
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 0 deletions.
84 changes: 84 additions & 0 deletions src/rocky/vsg/Motion.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* rocky c++
* Copyright 2023 Pelican Mapping
* MIT License
*/
#pragma once
#include <rocky/vsg/ECS.h>
#include <rocky/vsg/Transform.h>

namespace ROCKY_NAMESPACE
{
/**
* ECS Component applying simple motion to an object
*/
struct Motion
{
glm::dvec3 velocity;
glm::dvec3 acceleration;
};

/**
* ECS System to process Motion components
*/
class MotionSystem : public ECS::System
{
public:
MotionSystem(entt::registry& r) : ECS::System(r) { }

std::vector<entt::entity> updated;

//! Called periodically to update the transforms
void update(Runtime& runtime) override
{
updated.clear();

auto time = runtime.viewer->getFrameStamp()->time;

if (last_time != ECS::time_point::min())
{
// delta seconds since last tick:
double dt = 1e-9 * (double)(time - last_time).count();

// Join query all motions + transform pairs:
auto view = registry.group<Motion, Transform>();

for (auto&& [entity, motion, transform] : view.each())
{
const glm::dvec3 zero{ 0.0, 0.0, 0.0 };

if (motion.velocity != zero)
{
GeoPoint& pos = transform.position;
double save_z = pos.z;

auto pos_to_world = pos.srs.to(pos.srs.geocentricSRS());

// move the entity using a velocity vector in the local tangent plane
glm::dvec3 world;
pos_to_world((glm::dvec3)pos, world);
auto l2w = pos.srs.ellipsoid().geocentricToLocalToWorld(world);

world = l2w * (motion.velocity * dt);

vsg::dvec3 coord(world.x, world.y, world.z);
pos_to_world.inverse(coord, coord);

pos.x = coord.x, pos.y = coord.y;
pos.z = save_z;
transform.dirty();

updated.emplace_back(entity);
}

motion.velocity += motion.acceleration * dt;
};
}
last_time = time;
}

private:
//! Constructor
ECS::time_point last_time = ECS::time_point::min();
};
}
82 changes: 82 additions & 0 deletions src/rocky/vsg/Transform.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* rocky c++
* Copyright 2023 Pelican Mapping
* MIT License
*/
#pragma once
#include <rocky/vsg/GeoTransform.h>

namespace ROCKY_NAMESPACE
{
/**
* Spatial transformation component.
* Create with
* auto& transform = registry.emplace<Transform>(entity);
*
* A Transform may be safely updated asynchronously.
*/
struct Transform
{
//! Georeferenced position
GeoPoint position;

//! Local transform matrix (for rotation and scale, e.g.)
vsg::dmat4 localMatrix;

//! Whether the localMatrix is relative to a local tangent plane at
//! "position", versus a simple translated reference frame.
bool localTangentPlane = true;

//! Parent transform to apply before applying this one
Transform* parent = nullptr;

//! Underlying geotransform logic
vsg::ref_ptr<GeoTransform> node; // todo. move this to a separate component...?

Transform()
{
}

void setPosition(const GeoPoint& p)
{
position = p;
dirty();
}

void dirty()
{
if (!node)
node = GeoTransform::create();

node->setPosition(position);
node->localTangentPlane = localTangentPlane;
}

//! Returns true if the push succeeded (and a pop will be required)
inline bool push(vsg::RecordTraversal& rt, const vsg::dmat4& m)
{
if (node)
{
return node->push(rt, m * localMatrix);
}
else if (parent)
{
return parent->push(rt, m * localMatrix);
}
else return false;
}

//! Pops a transform applied if push() returned true.
inline void pop(vsg::RecordTraversal& rt)
{
if (node)
{
node->pop(rt);
}
else if (parent)
{
parent->pop(rt);
}
}
};
}

0 comments on commit a534e94

Please sign in to comment.