Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pipe wires #65

Merged
merged 1 commit into from
Feb 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/OSPData/adera/ph_engine.sturdy.gltf
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"type" : "Rocket",
"thrust" : 150000.0,
"Isp" : 100.0,
"fuel" : "lzdb:fuel"
"fueltype" : "lzdb:fuel"
},
{
"type" : "FreeEnergyGenerator"
Expand Down
2 changes: 1 addition & 1 deletion bin/OSPData/adera/ph_rcs.sturdy.gltf
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"type" : "Rocket",
"thrust" : 7000.0,
"Isp" : 225.0,
"fuel" : "lzdb:monoprop"
"fueltype" : "lzdb:fuel"
},
{
"type" : "FreeEnergyGenerator"
Expand Down
3 changes: 2 additions & 1 deletion bin/OSPData/adera/spamcan.sturdy.gltf
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@
},
{
"type" : "Rocket",
"thrust" : 1000.0
"thrust" : 1000.0,
"fueltype" : "lzdb:fuel"
},
{
"type" : "FreeEnergyGenerator"
Expand Down
102 changes: 55 additions & 47 deletions src/adera/Machines/Rocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,15 @@ WireOutput* MachineRocket::request_output(WireOutPort port)

std::vector<WireInput*> MachineRocket::existing_inputs()
{
/*std::vector<WireInput*> inputs;
std::vector<WireInput*> inputs;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems a bit weird to use a raw pointer for something that you know is always non-null.

std::reference_wrapper might be closer to what you really want.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Capital-Asterisk what do you think of this? I was just following the convention of the other existing_inputs() functions, should we change all of these to references instead of pointers?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want the entire wiring system dead, so there isn't really a point. Changing the syntax won't untangle the spaghetti.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah fair enough

inputs.reserve(3 + m_resourceLines.size());

inputs.insert(inputs.begin(), {&m_wiGimbal, &m_wiIgnition, &m_wiThrottle});
for (auto& resource : m_resourceLines)
{
inputs.push_back(&resource.m_lineIn);
inputs.push_back(&resource.m_source);
}
return inputs;*/
return {&m_wiGimbal, &m_wiIgnition, &m_wiThrottle};
return inputs;
}

std::vector<WireOutput*> MachineRocket::existing_outputs()
Expand Down Expand Up @@ -125,18 +124,23 @@ void SysMachineRocket::update_physics(ActiveScene& rScene)
bool fail = false;
for (auto& resource : machine.m_resourceLines)
{
auto const* src = m_scene.reg_try_get<MachineContainer>(resource.m_sourceEnt);
if (!src)
if (auto const* pipe = resource.m_source.get_if<wiretype::Pipe>();
pipe != nullptr)
{
std::cout << "Error: no source found\n";
fail = true;
break;
}
if (!src->check_contents().m_quantity > 0)
{
fail = true;
break;

if (auto const* src = rScene.reg_try_get<MachineContainer>(pipe->m_source);
src != nullptr)
{
uint64_t required = resource_units_required(rScene, machine,
pThrotPercent->m_value, resource);
if (src->check_contents().m_quantity > required)
{
continue;
}
}
}
fail = true;
break;
}
if (fail)
{
Expand Down Expand Up @@ -179,17 +183,17 @@ void SysMachineRocket::update_physics(ActiveScene& rScene)
rCompRb.m_inertiaDirty = true;

// Perform resource consumption calculation
float massFlowRateTot = thrustMag /
(phys::constants::g_0 * machine.m_params.m_specImpulse);
for (MachineRocket::ResourceInput const& resource : machine.m_resourceLines)
{
float massFlowRate = massFlowRateTot * resource.m_massRateFraction;
float massFlow = massFlowRate * m_scene.get_time_delta_fixed();
uint64_t required = resource.m_type->resource_quantity(massFlow);
auto* src = m_scene.reg_try_get<MachineContainer>(resource.m_sourceEnt);
uint64_t consumed = src->request_contents(required);
// Pipe must be non-null since we checked earlier
const auto& pipe = *resource.m_source.get_if<wiretype::Pipe>();
auto& src = rScene.reg_get<MachineContainer>(pipe.m_source);

uint64_t required = resource_units_required(rScene, machine,
pThrotPercent->m_value, resource);
uint64_t consumed = src.request_contents(required);
std::cout << "consumed " << consumed << " units of fuel, "
<< src->check_contents().m_quantity << " remaining\n";
<< src.check_contents().m_quantity << " remaining\n";
}

// Set output power level (for plume effect)
Expand Down Expand Up @@ -247,39 +251,43 @@ Machine& SysMachineRocket::instantiate(ActiveEnt ent, PrototypeMachine config,
params.m_maxThrust = std::get<double>(config.m_config["thrust"]);
params.m_specImpulse = std::get<double>(config.m_config["Isp"]);

MachineRocket::fuel_list_t inputs;
Package& pkg = m_scene.get_application().debug_find_package("lzdb");
DependRes<ShipResourceType> fuel = pkg.get<ShipResourceType>("fuel");
std::string const& fuelIdent = std::get<std::string>(config.m_config["fueltype"]);
Path resPath = decompose_path(fuelIdent);
Package& pkg = m_scene.get_application().debug_find_package(resPath.prefix);
DependRes<ShipResourceType> fuel = pkg.get<ShipResourceType>(resPath.identifier);

std::vector<MachineRocket::input_t> inputs;
if (!fuel.empty())
{
// TMP: finds the first non-empty fuel tank in the ship
// Only works as long as the fuselage is added before the engine

ActiveEnt foundTank = entt::null;
auto find_fuel = [this, &foundTank](ActiveEnt e)
{
if (auto* fuel = this->m_scene.reg_try_get<MachineContainer>(e);
fuel != nullptr && fuel->check_contents().m_quantity > 0)
{
foundTank = e;
return EHierarchyTraverseStatus::Stop;
}
return EHierarchyTraverseStatus::Continue;
};
auto const& parent = m_scene.reg_get<ACompHierarchy>(ent);
m_scene.hierarchy_traverse(parent.m_parent, find_fuel);
// endTMP

ActiveEnt fuelSource = foundTank;
MachineRocket::ResourceInput input = {std::move(fuel), 1.0f, fuelSource};
inputs.push_back(std::move(input));
inputs.push_back({std::move(fuel), 1.0f});
z-adams marked this conversation as resolved.
Show resolved Hide resolved
}

attach_plume_effect(ent);
return m_scene.reg_emplace<MachineRocket>(ent, params, inputs);
return m_scene.reg_emplace<MachineRocket>(ent, std::move(params), std::move(inputs));
}

Machine& SysMachineRocket::get(ActiveEnt ent)
{
return m_scene.reg_get<MachineRocket>(ent);//emplace(ent);
}

uint64_t SysMachineRocket::resource_units_required(
osp::active::ActiveScene const& scene,
MachineRocket const& machine, float throttle,
MachineRocket::ResourceInput const& resource)
{
float massFlowRate = resource_mass_flow_rate(machine,
throttle, resource);
float massFlow = massFlowRate * scene.get_time_delta_fixed();
return resource.m_type->resource_quantity(massFlow);
}

constexpr float SysMachineRocket::resource_mass_flow_rate(MachineRocket const& machine,
float throttle, MachineRocket::ResourceInput const& resource)
{
float thrustMag = machine.m_params.m_maxThrust * throttle;
float massFlowRateTot = thrustMag /
(phys::constants::g_0 * machine.m_params.m_specImpulse);

return massFlowRateTot * resource.m_massRateFraction;
}
134 changes: 78 additions & 56 deletions src/adera/Machines/Rocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,62 +32,27 @@
namespace adera::active::machines
{

class MachineRocket;


class SysMachineRocket :
public osp::active::SysMachine<SysMachineRocket, MachineRocket>
{
public:

static inline std::string smc_name = "Rocket";

SysMachineRocket(osp::active::ActiveScene &scene);

//void update_sensor();
void update_physics(osp::active::ActiveScene& rScene);

/**
* Attach a visual exhaust plume effect to MachineRocket
*
* Searches the hierarchy under the specified MachineRocket entity and
* attaches an ACompExhaustPlume to the rocket's plume node. A graphical
* exhaust plume effect will be attached to the node by SysExhaustPlume
* when it processes the component.
* @param ent The MachineRocket entity
*/
void attach_plume_effect(osp::active::ActiveEnt ent);

/**
* Attach a MachineRocket to an entity
*
* Also attempts to attach a plume component to the appropriate child node
* @param ent The entity that owns the MachineRocket
* @return The new MachineRocket instance
*/
osp::active::Machine& instantiate(osp::active::ActiveEnt ent,
osp::PrototypeMachine config, osp::BlueprintMachine settings) override;

osp::active::Machine& get(osp::active::ActiveEnt ent) override;

private:

osp::active::UpdateOrderHandle_t m_updatePhysics;
}; // SysMachineRocket

/**
*
*/
class MachineRocket : public osp::active::Machine
{
friend SysMachineRocket;
friend class SysMachineRocket;

using input_t = std::pair<osp::DependRes<ShipResourceType>, float>;
struct ResourceInput
{
ResourceInput(osp::DependRes<ShipResourceType> type,
float massRateFraction, osp::active::WireInput source)
: m_type(std::move(type))
, m_massRateFraction(massRateFraction)
, m_source(std::move(source))
{}

osp::DependRes<ShipResourceType> m_type;
float m_massRateFraction;
osp::active::ActiveEnt m_sourceEnt;
osp::active::WireInput m_source;
};
using fuel_list_t = std::vector<ResourceInput>;

struct Parameters
{
Expand All @@ -96,7 +61,7 @@ class MachineRocket : public osp::active::Machine
};

public:
MachineRocket(Parameters params, fuel_list_t& resources);
MachineRocket(Parameters params, std::vector<input_t> resources);
MachineRocket(MachineRocket &&move) noexcept;
MachineRocket& operator=(MachineRocket&& move) noexcept;

Expand All @@ -123,26 +88,83 @@ class MachineRocket : public osp::active::Machine
* @return normalized float [0,1] representing engine power output
*/
float current_output_power() const
{ return m_powerOutput; }
{
return m_powerOutput;
}

private:
osp::active::WireInput m_wiGimbal { this, "Gimbal" };
osp::active::WireInput m_wiIgnition { this, "Ignition" };
osp::active::WireInput m_wiThrottle { this, "Throttle" };
osp::active::WireInput m_wiGimbal{this, "Gimbal"};
osp::active::WireInput m_wiIgnition{this, "Ignition"};
osp::active::WireInput m_wiThrottle{this, "Throttle"};
std::vector<ResourceInput> m_resourceLines;

osp::active::ActiveEnt m_rigidBody { entt::null };
fuel_list_t m_resourceLines;
osp::active::ActiveEnt m_rigidBody{entt::null};
Parameters m_params;

// Rocket power output for the current frame
float m_powerOutput{0.0f};
}; // MachineRocket

inline MachineRocket::MachineRocket(Parameters params, fuel_list_t& resources)
class SysMachineRocket :
public osp::active::SysMachine<SysMachineRocket, MachineRocket>
{
public:

static inline std::string smc_name = "Rocket";

SysMachineRocket(osp::active::ActiveScene &scene);

//void update_sensor();
void update_physics(osp::active::ActiveScene& rScene);

/**
* Attach a visual exhaust plume effect to MachineRocket
*
* Searches the hierarchy under the specified MachineRocket entity and
* attaches an ACompExhaustPlume to the rocket's plume node. A graphical
* exhaust plume effect will be attached to the node by SysExhaustPlume
* when it processes the component.
* @param ent The MachineRocket entity
*/
void attach_plume_effect(osp::active::ActiveEnt ent);

/**
* Attach a MachineRocket to an entity
*
* Also attempts to attach a plume component to the appropriate child node
* @param ent The entity that owns the MachineRocket
* @return The new MachineRocket instance
*/
osp::active::Machine& instantiate(osp::active::ActiveEnt ent,
osp::PrototypeMachine config, osp::BlueprintMachine settings) override;

osp::active::Machine& get(osp::active::ActiveEnt ent) override;

private:
static uint64_t resource_units_required(
osp::active::ActiveScene const& scene,
MachineRocket const& machine, float throttle,
MachineRocket::ResourceInput const& resource);

constexpr static float resource_mass_flow_rate(MachineRocket const& machine,
float throttle, MachineRocket::ResourceInput const& resource);

osp::active::UpdateOrderHandle_t m_updatePhysics;
}; // SysMachineRocket

inline MachineRocket::MachineRocket(Parameters params, std::vector<input_t> resources)
: Machine(true)
, m_params(params)
, m_resourceLines(std::move(resources))
{ }
{
for (input_t& input : std::move(resources))
{
std::string resName = input.first->m_identifier;
m_resourceLines.emplace_back(
std::move(input.first),
input.second,
osp::active::WireInput{this, resName});
}
}

inline MachineRocket::MachineRocket(MachineRocket&& move) noexcept
: Machine(std::move(move))
Expand Down