Program Listing for File AgentVis.cpp
↰ Return to documentation for file (src/flamegpu/visualiser/AgentVis.cpp
)
// @todo - ifdef visualisation?
#include "flamegpu/visualiser/AgentVis.h"
#include <utility>
#include <string>
#include <memory>
#include "flamegpu/simulation/detail/CUDAAgent.h"
#include "flamegpu/model/AgentData.h"
#include "flamegpu/model/AgentDescription.h"
#include "flamegpu/visualiser/color/ColorFunction.h"
#include "flamegpu/visualiser/color/StaticColor.h"
#include "flamegpu/visualiser/color/AutoPalette.h"
#include "flamegpu/visualiser/FLAMEGPU_Visualisation.h"
namespace flamegpu {
namespace visualiser {
AgentVisData::AgentVisData(detail::CUDAAgent &_agent, const std::shared_ptr<AutoPalette>& autopalette)
: owned_auto_palette(nullptr)
, agent(_agent)
, agentData(std::const_pointer_cast<const AgentData>(_agent.getAgentDescription().agent)) {
const CAgentDescription agent_desc = _agent.getAgentDescription();
if (agent_desc.hasVariable("x") &&
agent_desc.getVariableType("x") == std::type_index(typeid(float)) &&
agent_desc.getVariableLength("x") == 1) {
core_tex_buffers[TexBufferConfig::Position_x].agentVariableName = "x";
}
if (agent_desc.hasVariable("y") &&
agent_desc.getVariableType("y") == std::type_index(typeid(float)) &&
agent_desc.getVariableLength("y") == 1) {
core_tex_buffers[TexBufferConfig::Position_y].agentVariableName = "y";
}
if (agent_desc.hasVariable("z") &&
agent_desc.getVariableType("z") == std::type_index(typeid(float)) &&
agent_desc.getVariableLength("z") == 1) {
core_tex_buffers[TexBufferConfig::Position_z].agentVariableName = "z";
}
if (autopalette) {
defaultConfig.color_shader_src = StaticColor(autopalette->next()).getSrc(0); // Arg is not used by static color, so 0 can be passed
}
}
void AgentVisData::initBindings(std::unique_ptr<FLAMEGPU_Visualisation>& vis) {
// Pass each state's vis config to the visualiser
for (auto& state : agentData->states) {
// For each agent state, give the visualiser
// vis config
AgentStateConfig& vc = defaultConfig; // Default to parent if child hasn't been configured
const auto state_it = states.find(state);
if (state_it != states.end()) {
if (!state_it->second->visible) {
// Skip agent states marked hidden
continue;
}
vc = state_it->second->config;
}
vis->addAgentState(agentData->name, state, vc, core_tex_buffers, vc.tex_buffers);
}
}
bool AgentVisData::requestBufferResizes(std::unique_ptr<FLAMEGPU_Visualisation>& vis, bool force) {
unsigned int agents_requested = 0;
for (auto& state : agentData->states) {
const auto state_it = states.find(state);
if (state_it != states.end()) {
if (!state_it->second->visible) {
// Skip agent states marked hidden
continue;
}
}
auto& state_map = agent.state_map.at(state);
vis->requestBufferResizes(agentData->name, state, state_map->getSize(), force);
agents_requested += state_map->getSize();
}
return agents_requested;
}
void AgentVisData::updateBuffers(std::unique_ptr<FLAMEGPU_Visualisation>& vis) {
for (auto& state : agentData->states) {
AgentStateConfig& state_config = defaultConfig; // Default to parent if child hasn't been configured
const auto state_it = states.find(state);
if (state_it != states.end()) {
if (!state_it->second->visible) {
// Skip agent states marked hidden
continue;
}
state_config = state_it->second->config;
}
auto& state_data_map = agent.state_map.at(state);
// Update buffer pointers inside the map
// These get changed per state, but should be fine
for (auto& tb : core_tex_buffers) {
tb.second.t_d_ptr = state_data_map->getVariablePointer(tb.second.agentVariableName);
}
for (auto& tb : state_config.tex_buffers) {
tb.second.t_d_ptr = state_data_map->getVariablePointer(tb.second.agentVariableName);
}
// Pass the updated map to the update function
vis->updateAgentStateBuffer(agentData->name, state, state_data_map->getSize(), core_tex_buffers, state_config.tex_buffers);
}
}
AgentVis::AgentVis(std::shared_ptr<AgentVisData> _data)
: data(std::move(_data)) { }
AgentStateVis AgentVis::State(const std::string &state_name) {
// If state exists
if (data->agentData->states.find(state_name) != data->agentData->states.end()) {
// If state is not already in vis map
auto visAgentState = data->states.find(state_name);
if (visAgentState == data->states.end()) {
// Create new vis agent
auto rtn = data->states.emplace(state_name, std::make_shared<AgentStateVisData>(std::const_pointer_cast<const AgentVisData>(data), state_name)).first->second;
auto ap = data->auto_palette.lock();
if (ap) {
rtn->config.color_shader_src = StaticColor(ap->next()).getSrc(0); // Arg is not used by static color, so 0 can be passed
}
return AgentStateVis(rtn);
}
return AgentStateVis(visAgentState->second);
}
THROW exception::InvalidAgentName("State '%s' was not found within agent '%s', "
"in AgentVis::State()\n",
state_name.c_str(), data->agentData->name.c_str());
}
void AgentVis::setXVariable(const std::string &var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setXVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation position x variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setXVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Position_xy);
data->core_tex_buffers.erase(TexBufferConfig::Position_xyz);
data->core_tex_buffers[TexBufferConfig::Position_x].agentVariableName = var_name;
}
void AgentVis::setYVariable(const std::string &var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setYVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation position Y variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setYVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Position_xy);
data->core_tex_buffers.erase(TexBufferConfig::Position_xyz);
data->core_tex_buffers[TexBufferConfig::Position_y].agentVariableName = var_name;
}
void AgentVis::setZVariable(const std::string &var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setZVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation position z variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setZVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Position_xy);
data->core_tex_buffers.erase(TexBufferConfig::Position_xyz);
data->core_tex_buffers[TexBufferConfig::Position_z].agentVariableName = var_name;
}
void AgentVis::setXYVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setXYVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 2) {
THROW exception::InvalidAgentVar("Visualisation position x variable must be type float[2], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setXYVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Position_x);
data->core_tex_buffers.erase(TexBufferConfig::Position_y);
data->core_tex_buffers.erase(TexBufferConfig::Position_z);
data->core_tex_buffers.erase(TexBufferConfig::Position_xyz);
data->core_tex_buffers[TexBufferConfig::Position_xy].agentVariableName = var_name;
}
void AgentVis::setXYZVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setXYZVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 3) {
THROW exception::InvalidAgentVar("Visualisation position x variable must be type float[3], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setXYZVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Position_x);
data->core_tex_buffers.erase(TexBufferConfig::Position_y);
data->core_tex_buffers.erase(TexBufferConfig::Position_z);
data->core_tex_buffers.erase(TexBufferConfig::Position_xy);
data->core_tex_buffers[TexBufferConfig::Position_xyz].agentVariableName = var_name;
}
void AgentVis::setForwardXVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setForwardXVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation forward x variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setForwardXVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Heading);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xz);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xyz);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hp);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
data->core_tex_buffers[TexBufferConfig::Forward_x].agentVariableName = var_name;
}
void AgentVis::setForwardYVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setForwardYVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation forward y variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setForwardYVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Pitch);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xyz);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hp);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
data->core_tex_buffers[TexBufferConfig::Forward_y].agentVariableName = var_name;
}
void AgentVis::setForwardZVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setForwardZVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation forward z variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setForwardZVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Heading);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xz);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xyz);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hp);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
data->core_tex_buffers[TexBufferConfig::Forward_z].agentVariableName = var_name;
}
void AgentVis::setForwardXZVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setForwardXZVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 2) {
THROW exception::InvalidAgentVar("Visualisation forward xz variable must be type float[2], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setForwardXZVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Heading);
data->core_tex_buffers.erase(TexBufferConfig::Forward_x);
data->core_tex_buffers.erase(TexBufferConfig::Forward_y);
data->core_tex_buffers.erase(TexBufferConfig::Forward_z);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xyz);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hp);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
data->core_tex_buffers[TexBufferConfig::Forward_xz].agentVariableName = var_name;
}
void AgentVis::setForwardXYZVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setForwardXYZVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 3) {
THROW exception::InvalidAgentVar("Visualisation forward xyz variable must be type float[2], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setForwardXYZVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Heading);
data->core_tex_buffers.erase(TexBufferConfig::Forward_x);
data->core_tex_buffers.erase(TexBufferConfig::Forward_z);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xz);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hp);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
data->core_tex_buffers[TexBufferConfig::Forward_xyz].agentVariableName = var_name;
}
void AgentVis::setUpXVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setUpXVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation up x variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setUpXVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Bank);
data->core_tex_buffers.erase(TexBufferConfig::Up_xyz);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
data->core_tex_buffers[TexBufferConfig::Up_x].agentVariableName = var_name;
}
void AgentVis::setUpYVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setUpYVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation up y variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setUpYVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Bank);
data->core_tex_buffers.erase(TexBufferConfig::Up_xyz);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
data->core_tex_buffers[TexBufferConfig::Up_y].agentVariableName = var_name;
}
void AgentVis::setUpZVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setUpZVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation up z variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setUpZVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Bank);
data->core_tex_buffers.erase(TexBufferConfig::Up_xyz);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
data->core_tex_buffers[TexBufferConfig::Up_z].agentVariableName = var_name;
}
void AgentVis::setUpXYZVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setUpXYZVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 3) {
THROW exception::InvalidAgentVar("Visualisation up xyz variable must be type float[3], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setUpXYZVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Bank);
data->core_tex_buffers.erase(TexBufferConfig::Up_x);
data->core_tex_buffers.erase(TexBufferConfig::Up_y);
data->core_tex_buffers.erase(TexBufferConfig::Up_z);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
data->core_tex_buffers[TexBufferConfig::Up_xyz].agentVariableName = var_name;
}
void AgentVis::setYawVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setYawVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation yaw variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setYawVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Forward_x);
data->core_tex_buffers.erase(TexBufferConfig::Forward_z);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xz);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xyz);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hp);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
data->core_tex_buffers[TexBufferConfig::Heading].agentVariableName = var_name;
}
void AgentVis::setPitchVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setPitchVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation pitch variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setPitchVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Forward_y);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xyz);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hp);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
data->core_tex_buffers[TexBufferConfig::Pitch].agentVariableName = var_name;
}
void AgentVis::setRollVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setRollVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation roll variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setRollVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Up_x);
data->core_tex_buffers.erase(TexBufferConfig::Up_y);
data->core_tex_buffers.erase(TexBufferConfig::Up_z);
data->core_tex_buffers.erase(TexBufferConfig::Up_xyz);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
data->core_tex_buffers[TexBufferConfig::Bank].agentVariableName = var_name;
}
void AgentVis::setDirectionYPVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setDirectionYPVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 2) {
THROW exception::InvalidAgentVar("Visualisation direction yaw/pitch variable must be type float[2], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setDirectionYPVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Forward_x);
data->core_tex_buffers.erase(TexBufferConfig::Forward_z);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xz);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xyz);
data->core_tex_buffers.erase(TexBufferConfig::Heading);
data->core_tex_buffers.erase(TexBufferConfig::Pitch);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
data->core_tex_buffers[TexBufferConfig::Heading].agentVariableName = var_name;
}
void AgentVis::setDirectionYPRVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setDirectionYPRVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 3) {
THROW exception::InvalidAgentVar("Visualisation direction yaw/pitch/roll variable must be type float[3], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setDirectionYPRVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Forward_x);
data->core_tex_buffers.erase(TexBufferConfig::Forward_z);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xz);
data->core_tex_buffers.erase(TexBufferConfig::Forward_xyz);
data->core_tex_buffers.erase(TexBufferConfig::Up_x);
data->core_tex_buffers.erase(TexBufferConfig::Up_y);
data->core_tex_buffers.erase(TexBufferConfig::Up_z);
data->core_tex_buffers.erase(TexBufferConfig::Up_xyz);
data->core_tex_buffers.erase(TexBufferConfig::Heading);
data->core_tex_buffers.erase(TexBufferConfig::Pitch);
data->core_tex_buffers.erase(TexBufferConfig::Bank);
data->core_tex_buffers.erase(TexBufferConfig::Direction_hp);
data->core_tex_buffers[TexBufferConfig::Heading].agentVariableName = var_name;
}
void AgentVis::setUniformScaleVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setUniformScaleVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation scale variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setUniformScaleVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::Scale_x);
data->core_tex_buffers.erase(TexBufferConfig::Scale_y);
data->core_tex_buffers.erase(TexBufferConfig::Scale_z);
data->core_tex_buffers.erase(TexBufferConfig::Scale_xy);
data->core_tex_buffers.erase(TexBufferConfig::Scale_xyz);
data->core_tex_buffers[TexBufferConfig::UniformScale].agentVariableName = var_name;
}
void AgentVis::setScaleXVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setScaleXVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation scale x variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setScaleXVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::UniformScale);
data->core_tex_buffers.erase(TexBufferConfig::Scale_xy);
data->core_tex_buffers.erase(TexBufferConfig::Scale_xyz);
data->core_tex_buffers[TexBufferConfig::Scale_x].agentVariableName = var_name;
}
void AgentVis::setScaleYVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setScaleYVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation scale y variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setScaleYVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::UniformScale);
data->core_tex_buffers.erase(TexBufferConfig::Scale_xy);
data->core_tex_buffers.erase(TexBufferConfig::Scale_xyz);
data->core_tex_buffers[TexBufferConfig::Scale_y].agentVariableName = var_name;
}
void AgentVis::setScaleZVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setScaleZVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation scale z variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setScaleZVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::UniformScale);
data->core_tex_buffers.erase(TexBufferConfig::Scale_xy);
data->core_tex_buffers.erase(TexBufferConfig::Scale_xyz);
data->core_tex_buffers[TexBufferConfig::Scale_z].agentVariableName = var_name;
}
void AgentVis::setScaleXYVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setScaleXYVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 2) {
THROW exception::InvalidAgentVar("Visualisation scale xy variable must be type float[2], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setScaleXYVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::UniformScale);
data->core_tex_buffers.erase(TexBufferConfig::Scale_x);
data->core_tex_buffers.erase(TexBufferConfig::Scale_y);
data->core_tex_buffers.erase(TexBufferConfig::Scale_z);
data->core_tex_buffers.erase(TexBufferConfig::Scale_xyz);
data->core_tex_buffers[TexBufferConfig::Scale_xy].agentVariableName = var_name;
}
void AgentVis::setScaleXYZVariable(const std::string& var_name) {
auto it = data->agentData->variables.find(var_name);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setScaleXYZVariable()\n",
var_name.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 3) {
THROW exception::InvalidAgentVar("Visualisation scale xyz variable must be type float[3], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setScaleXYZVariable()\n",
data->agentData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
}
data->core_tex_buffers.erase(TexBufferConfig::UniformScale);
data->core_tex_buffers.erase(TexBufferConfig::Scale_x);
data->core_tex_buffers.erase(TexBufferConfig::Scale_y);
data->core_tex_buffers.erase(TexBufferConfig::Scale_z);
data->core_tex_buffers.erase(TexBufferConfig::Scale_xy);
data->core_tex_buffers[TexBufferConfig::Scale_xyz].agentVariableName = var_name;
}
void AgentVis::clearXVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Position_x);
}
void AgentVis::clearYVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Position_y);
}
void AgentVis::clearZVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Position_z);
}
void AgentVis::clearXYVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Position_xy);
}
void AgentVis::clearXYZVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Position_xyz);
}
void AgentVis::clearForwardXVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Forward_x);
}
void AgentVis::clearForwardYVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Forward_y);
}
void AgentVis::clearForwardZVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Forward_z);
}
void AgentVis::clearForwardXZVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Forward_xz);
}
void AgentVis::clearForwardXYZVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Forward_xyz);
}
void AgentVis::clearUpXVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Up_x);
}
void AgentVis::clearUpYVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Up_y);
}
void AgentVis::clearUpZVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Up_z);
}
void AgentVis::clearUpXYZVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Up_xyz);
}
void AgentVis::clearYawVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Heading);
}
void AgentVis::clearPitchVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Pitch);
}
void AgentVis::clearRollVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Bank);
}
void AgentVis::clearDirectionYPVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Direction_hp);
}
void AgentVis::clearDirectionYPRVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Direction_hpb);
}
void AgentVis::clearUniformScaleVariable() {
data->core_tex_buffers.erase(TexBufferConfig::UniformScale);
}
void AgentVis::clearScaleXVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Scale_x);
}
void AgentVis::clearScaleYVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Scale_y);
}
void AgentVis::clearScaleZVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Scale_z);
}
void AgentVis::clearScaleXYVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Scale_xy);
}
void AgentVis::clearScaleXYZVariable() {
data->core_tex_buffers.erase(TexBufferConfig::Scale_xyz);
}
std::string AgentVis::getXVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Position_x);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getYVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Position_y);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getZVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Position_z);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getXYVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Position_xy);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getXYZVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Position_xyz);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getForwardXVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Forward_x);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getForwardYVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Forward_y);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getForwardZVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Forward_z);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getUpXVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Up_x);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getForwardXZVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Forward_xz);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getForwardXYZVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Forward_xyz);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getUpYVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Up_y);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getUpZVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Up_z);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getUpXYZVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Up_xyz);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getYawVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Heading);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getPitchVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Pitch);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getRollVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Bank);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getDirectionYPVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Direction_hp);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getDirectionYPRVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Direction_hpb);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getUniformScaleVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::UniformScale);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getScaleXVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Scale_x);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getScaleYVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Scale_y);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getScaleZVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Scale_z);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getScaleXYVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Scale_xy);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
std::string AgentVis::getScaleXYZVariable() const {
const auto it = data->core_tex_buffers.find(TexBufferConfig::Scale_xyz);
return it != data->core_tex_buffers.end() ? it->second.agentVariableName : "";
}
void AgentVis::setModel(const std::string &modelPath, const std::string &texturePath) {
AgentStateConfig::setString(&data->defaultConfig.model_path, modelPath);
if (!texturePath.empty()) {
AgentStateConfig::setString(&data->defaultConfig.model_texture, texturePath);
clearColor();
}
// Apply to all states which haven't had the setting overriden
for (auto &s : data->states) {
if (!s.second->configFlags.model_path) {
AgentStateConfig::setString(&s.second->config.model_path, modelPath);
if (!texturePath.empty())
AgentStateConfig::setString(&s.second->config.model_texture, texturePath);
}
}
}
void AgentVis::setModel(const Stock::Models::Model &model) {
AgentStateConfig::setString(&data->defaultConfig.model_path, model.modelPath);
if (model.texturePath && model.texturePath[0] != '\0') {
AgentStateConfig::setString(&data->defaultConfig.model_texture, model.texturePath);
clearColor();
}
// Apply to all states which haven't had the setting overridden
for (auto &s : data->states) {
if (!s.second->configFlags.model_path) {
AgentStateConfig::setString(&s.second->config.model_path, model.modelPath);
if (model.texturePath && model.texturePath[0] != '\0')
AgentStateConfig::setString(&s.second->config.model_texture, model.texturePath);
}
}
}
void AgentVis::setKeyFrameModel(const std::string& modelPathA, const std::string& modelPathB, const std::string& lerpVariableName, const std::string& texturePath) {
auto it = data->agentData->variables.find(lerpVariableName);
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' was not found within agent '%s', "
"in AgentVis::setKeyFrameModel()\n",
lerpVariableName.c_str(), data->agentData->name.c_str());
} else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
THROW exception::InvalidAgentVar("Visualisation animation lerp variable must be type float[1], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setKeyFrameModel()\n",
data->agentData->name.c_str(), lerpVariableName.c_str(), it->second.type.name(), it->second.elements);
}
AgentStateConfig::setString(&data->defaultConfig.model_path, modelPathA);
AgentStateConfig::setString(&data->defaultConfig.model_pathB, modelPathB);
if (!texturePath.empty()) {
AgentStateConfig::setString(&data->defaultConfig.model_texture, texturePath);
clearColor();
}
data->core_tex_buffers.erase(TexBufferConfig::AnimationLerp);
data->core_tex_buffers[TexBufferConfig::AnimationLerp].agentVariableName = lerpVariableName;
// Apply to all states which haven't had the setting overridden
for (auto& s : data->states) {
if (!s.second->configFlags.model_path) {
AgentStateConfig::setString(&s.second->config.model_path, modelPathA);
AgentStateConfig::setString(&s.second->config.model_pathB, modelPathB);
if (!texturePath.empty()) {
AgentStateConfig::setString(&s.second->config.model_texture, texturePath);
// Clear colour in state
s.second->config.color_shader_src = "";
}
}
}
}
void AgentVis::setKeyFrameModel(const Stock::Models::KeyFrameModel& model, const std::string& lerpVariableName) {
setKeyFrameModel(model.modelPathA, model.modelPathB, lerpVariableName, model.texturePath ? model.texturePath : "");
}
void AgentVis::setModelScale(float xLen, float yLen, float zLen) {
if (xLen <= 0 || yLen <= 0 || zLen <= 0) {
THROW exception::InvalidArgument("AgentVis::setModelScale(): Invalid argument, lengths must all be positive.\n");
}
data->defaultConfig.model_scale[0] = xLen;
data->defaultConfig.model_scale[1] = yLen;
data->defaultConfig.model_scale[2] = zLen;
// Apply to all states which haven't had the setting overriden
for (auto &s : data->states) {
if (!s.second->configFlags.model_scale) {
s.second->config.model_scale[0] = xLen;
s.second->config.model_scale[1] = yLen;
s.second->config.model_scale[2] = zLen;
}
}
}
void AgentVis::setModelScale(float maxLen) {
if (maxLen <= 0) {
THROW exception::InvalidArgument("AgentVis::setModelScale(): Invalid argument, maxLen must be positive.\n");
}
data->defaultConfig.model_scale[0] = -maxLen;
// Apply to all states which haven't had the setting overriden
for (auto &s : data->states) {
if (!s.second->configFlags.model_scale) {
s.second->config.model_scale[0] = -maxLen;
}
}
}
void AgentVis::setAutoPalette(const Palette& ap) {
data->owned_auto_palette = std::make_shared<AutoPalette>(ap);
data->auto_palette = data->owned_auto_palette;
}
void AgentVis::setColor(const ColorFunction& cf) {
// Validate agent variable exists
unsigned int elements = 0;
if (!cf.getAgentVariableName().empty()) {
const auto it = data->agentData->variables.find(cf.getAgentVariableName());
if (it == data->agentData->variables.end()) {
THROW exception::InvalidAgentVar("Variable '%s' bound to color function was not found within agent '%s', "
"in AgentVis::setColor()\n",
cf.getAgentVariableName().c_str(), data->agentData->name.c_str());
}
if (it->second.type != cf.getAgentVariableRequiredType() || it->second.elements <= cf.getAgentArrayVariableElement()) {
THROW exception::InvalidAgentVar("Visualisation color function variable must be type %s[>%u], agent '%s' variable '%s' is type %s[%u], "
"in AgentVis::setColor()\n",
cf.getAgentVariableRequiredType().name(), cf.getAgentArrayVariableElement(), data->agentData->name.c_str(), cf.getAgentVariableName().c_str(), it->second.type.name(), it->second.elements);
}
elements = it->second.elements;
}
// Remove old, we only ever want 1 color value
data->defaultConfig.tex_buffers.erase(TexBufferConfig::Color);
if (!cf.getAgentVariableName().empty() && !cf.getSamplerName().empty())
data->defaultConfig.tex_buffers.emplace(TexBufferConfig::Color, CustomTexBufferConfig{ cf.getAgentVariableName(), cf.getSamplerName(), cf.getAgentArrayVariableElement(), elements });
data->defaultConfig.color_shader_src = cf.getSrc(elements);
data->auto_palette.reset();
data->owned_auto_palette = nullptr;
// Clear texture, can't have both colour and texture
if (data->defaultConfig.model_texture) {
free(const_cast<char*>(data->defaultConfig.model_texture));
}
}
void AgentVis::clearColor() {
data->defaultConfig.tex_buffers.erase(TexBufferConfig::Color);
data->defaultConfig.color_shader_src = "";
data->auto_palette.reset();
data->owned_auto_palette = nullptr;
}
} // namespace visualiser
} // namespace flamegpu