Skip to content

Commit

Permalink
Tuning: fixups of prop/flexbody tweaks.
Browse files Browse the repository at this point in the history
Code changes:
* TuneupFileFormat: just renamed `Xrot` to `Xrotation`
* CacheSystem.cpp: Fixed protected elements not being reset with Reset btn.
* AddonPartFileFormat: Fixed `addonpart_tweak_prop/_flexbody` not being parsed at all.
* FlexBody, FlexFactory: added 'orig mesh name' field to flexbody, for UIs.
* ActorSpawner: Pass ID and orig mesh name to placeholder-flexbody.
* GfxActor: fixed crash when rendering actor with a flexbody removed via tuneup/addonpart. The problem was `FinishFlexbodyTasks()` processing placeholder flexbodies. Now using `isVisible()`.
  • Loading branch information
ohlidalp committed Feb 4, 2024
1 parent 7f1c771 commit 9551d05
Show file tree
Hide file tree
Showing 13 changed files with 169 additions and 43 deletions.
18 changes: 11 additions & 7 deletions source/main/gfx/GfxActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2996,8 +2996,13 @@ void RoR::GfxActor::UpdateFlexbodies()

for (FlexBody* fb: m_flexbodies)
{
const int camera_mode = fb->getCameraMode();
if ((camera_mode == -2) || (camera_mode == m_simbuf.simbuf_cur_cinecam))
// Update visibility
fb->setVisible(
fb->getCameraMode() == CAMERA_MODE_ALWAYS_VISIBLE
|| fb->getCameraMode() == m_simbuf.simbuf_cur_cinecam);

// Update visible on background thread
if (fb->isVisible())
{
auto func = std::function<void()>([fb]()
{
Expand All @@ -3006,10 +3011,6 @@ void RoR::GfxActor::UpdateFlexbodies()
auto task_handle = App::GetThreadPool()->RunTask(func);
m_flexbody_tasks.push_back(task_handle);
}
else
{
fb->setVisible(false);
}
}
}

Expand Down Expand Up @@ -3037,7 +3038,10 @@ void RoR::GfxActor::FinishFlexbodyTasks()
}
for (FlexBody* fb: m_flexbodies)
{
fb->updateFlexbodyVertexBuffers();
if (fb->isVisible())
{
fb->updateFlexbodyVertexBuffers();
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions source/main/gui/panels/GUI_TopMenubar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1652,7 +1652,7 @@ void TopMenubar::Draw(float dt)
if (p.pp_beacon_type == 'L' || p.pp_beacon_type == 'R' || p.pp_beacon_type == 'w')
{
ImGui::SameLine();
ImGui::TextDisabled("(!)");
ImGui::TextDisabled("(special!)");
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
Expand All @@ -1663,7 +1663,7 @@ void TopMenubar::Draw(float dt)
else if (p.pp_wheel_mesh_obj)
{
ImGui::SameLine();
ImGui::TextDisabled("(!)");
ImGui::TextDisabled("(special!)");
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
Expand Down
2 changes: 1 addition & 1 deletion source/main/physics/ActorSpawner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1500,7 +1500,7 @@ void ActorSpawner::ProcessFlexbody(RigDef::Flexbody& def)
if (TuneupUtil::isFlexbodyRemoved(m_actor, flexbody_id))
{
// Create placeholder
m_actor->m_gfx_actor->m_flexbodies.emplace_back(new FlexBody(FlexBody::TUNING_PLACEHOLDER));
m_actor->m_gfx_actor->m_flexbodies.emplace_back(new FlexBody(FlexBody::TUNING_PLACEHOLDER, flexbody_id, def.mesh_name));
return;
}

Expand Down
2 changes: 1 addition & 1 deletion source/main/physics/ActorSpawner.h
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ class ActorSpawner
int m_first_wing_index;
std::vector<CabTexcoord> m_oldstyle_cab_texcoords;
std::vector<CabSubmesh> m_oldstyle_cab_submeshes;
RigDef::Keyword m_current_keyword; //!< For error reports
RigDef::Keyword m_current_keyword = RigDef::Keyword::INVALID; //!< For error reports
std::shared_ptr<RigDef::Document::Module> m_current_module; //!< For resolving addonparts
std::map<Ogre::String, unsigned int> m_named_nodes;
/// @}
Expand Down
29 changes: 15 additions & 14 deletions source/main/physics/flex/FlexBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,9 +519,11 @@ FlexBody::FlexBody(
}
}

FlexBody::FlexBody(FlexBodyPlaceholder_t ticket)
FlexBody::FlexBody(FlexBodyPlaceholder_t ticket, FlexbodyID_t id, const std::string& orig_meshname)
{
m_camera_mode = CAMERA_MODE_ALWAYS_HIDDEN;
m_id = id;
m_orig_mesh_name = orig_meshname;
}

FlexBody::~FlexBody()
Expand Down Expand Up @@ -554,6 +556,15 @@ FlexBody::~FlexBody()
m_scene_entity = nullptr;
}

bool FlexBody::isVisible() const
{
// Scene node is NULL if disabled via addonpart/tuneup.
return m_scene_node
&& m_scene_node->isInSceneGraph()
&& m_scene_node->getAttachedObject(0)->isVisible();

}

void FlexBody::setVisible(bool visible)
{
if (m_scene_node)
Expand Down Expand Up @@ -608,6 +619,9 @@ void FlexBody::computeFlexbody()

void FlexBody::updateFlexbodyVertexBuffers()
{
if (!m_scene_node) // Disabled via addonpart/tuneup
return;

Vector3 *ppt = m_dst_pos;
Vector3 *npt = m_dst_normals;
if (m_uses_shared_vertex_data)
Expand Down Expand Up @@ -679,19 +693,6 @@ void FlexBody::updateBlend() //so easy!
}
}

std::string FlexBody::getOrigMeshName()
{
std::string meshname = m_scene_entity->getMesh()->getName();
// Cut off the generated '_FlexBody_#@Actor_#' part
// TODO: fix the resource management to create resource group for each actor (currently done for each repo ZIP) - then we won't need those unique tokens anymore.
size_t pos = meshname.find("_FlexBody_");
if (pos != std::string::npos)
{
meshname = meshname.substr(0, pos);
}
return meshname;
}

int evalNodeDistance(NodeNum_t a, NodeNum_t b)
{
if (a > b)
Expand Down
6 changes: 4 additions & 2 deletions source/main/physics/flex/FlexBody.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class FlexBody
typedef int FlexBodyPlaceholder_t;
static const FlexBodyPlaceholder_t TUNING_PLACEHOLDER = -11;

FlexBody(FlexBodyPlaceholder_t);
FlexBody(FlexBodyPlaceholder_t, FlexbodyID_t id, const std::string& orig_meshname);
~FlexBody();

void reset();
Expand All @@ -76,6 +76,7 @@ class FlexBody
void computeFlexbody(); //!< Updates mesh deformation; works on CPU using local copy of vertex data.
void updateFlexbodyVertexBuffers();

bool isVisible() const;
void setVisible(bool visible);

void setFlexbodyCastShadow(bool val);
Expand All @@ -84,7 +85,7 @@ class FlexBody
Locator_t& getVertexLocator(int vert) { ROR_ASSERT((size_t)vert < m_vertex_count); return m_locators[vert]; }
Ogre::Vector3 getVertexPos(int vert) { ROR_ASSERT((size_t)vert < m_vertex_count); return m_dst_pos[vert] + m_flexit_center; }
Ogre::Entity* getEntity() { return m_scene_entity; }
std::string getOrigMeshName();
const std::string& getOrigMeshName() const { return m_orig_mesh_name; }
std::vector<NodeNum_t>& getForsetNodes() { return m_forset_nodes; };
std::string getOrigMeshInfo() { return m_orig_mesh_info; }
std::string getLiveMeshInfo() { return RoR::PrintMeshInfo("Live", m_scene_entity->getMesh()); }
Expand Down Expand Up @@ -137,6 +138,7 @@ class FlexBody
// Diagnostic data, not used for calculations
std::vector<NodeNum_t> m_forset_nodes;
std::string m_orig_mesh_info;
std::string m_orig_mesh_name;
};

/// @} // addtogroup Flex
Expand Down
1 change: 1 addition & 0 deletions source/main/physics/flex/FlexFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ FlexBody* FlexFactory::CreateFlexBody(
m_flexbody_cache.AddItemToSave(new_flexbody);
}
new_flexbody->m_id = flexbody_id;
new_flexbody->m_orig_mesh_name = common_mesh->getName();
return new_flexbody;
}

Expand Down
3 changes: 3 additions & 0 deletions source/main/resources/CacheSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1740,6 +1740,9 @@ void CacheSystem::ModifyProject(ModifyProjectRequest* request)
tuneup_entry->tuneup_def->use_addonparts.clear();
tuneup_entry->tuneup_def->wheel_tweaks.clear();
tuneup_entry->tuneup_def->node_tweaks.clear();
tuneup_entry->tuneup_def->protected_flexbodies.clear();
tuneup_entry->tuneup_def->protected_props.clear();
tuneup_entry->tuneup_def->protected_wheels.clear();
break;

default:
Expand Down
16 changes: 8 additions & 8 deletions source/main/resources/CacheSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,14 @@ enum class ModifyProjectRequestType
NONE,
TUNEUP_USE_ADDONPART_SET, //!< 'subject' is addonpart filename.
TUNEUP_USE_ADDONPART_RESET, //!< 'subject' is addonpart filename.
TUNEUP_REMOVE_PROP_SET, //!< 'subject' is mesh name.
TUNEUP_REMOVE_PROP_RESET, //!< 'subject' is mesh name.
TUNEUP_REMOVE_FLEXBODY_SET, //!< 'subject' is mesh name.
TUNEUP_REMOVE_FLEXBODY_RESET,//!< 'subject' is mesh name.
TUNEUP_PROTECTED_PROP_SET, //!< 'subject' is mesh name.
TUNEUP_PROTECTED_PROP_RESET, //!< 'subject' is mesh name.
TUNEUP_PROTECTED_FLEXBODY_SET, //!< 'subject' is mesh name.
TUNEUP_PROTECTED_FLEXBODY_RESET,//!< 'subject' is mesh name.
TUNEUP_REMOVE_PROP_SET, //!< 'subject_id' is prop ID.
TUNEUP_REMOVE_PROP_RESET, //!< 'subject_id' is prop ID.
TUNEUP_REMOVE_FLEXBODY_SET, //!< 'subject_id' is flexbody ID.
TUNEUP_REMOVE_FLEXBODY_RESET,//!< 'subject_id' is flexbody ID.
TUNEUP_PROTECTED_PROP_SET, //!< 'subject' is prop ID.
TUNEUP_PROTECTED_PROP_RESET, //!< 'subject' is prop ID.
TUNEUP_PROTECTED_FLEXBODY_SET, //!< 'subject' is flexbody ID.
TUNEUP_PROTECTED_FLEXBODY_RESET,//!< 'subject' is flexbody ID.
PROJECT_LOAD_TUNEUP, //!< 'subject' is tuneup filename. This overwrites the auto-generated tuneup with the save.
PROJECT_RESET_TUNEUP, //!< 'subject' is empty. This resets the auto-generated tuneup to orig. values.
};
Expand Down
117 changes: 115 additions & 2 deletions source/main/resources/addonpart_fileformat/AddonPartFileFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ void AddonPartUtility::ResolveUnwantedAndTweakedElements(TuneupDefPtr& tuneup, C
this->ProcessTweakWheel();
else if (m_context->getTokKeyword() == "addonpart_tweak_node")
this->ProcessTweakNode();
else if (m_context->getTokKeyword() == "addonpart_tweak_prop")
this->ProcessTweakProp();
else if (m_context->getTokKeyword() == "addonpart_tweak_flexbody")
this->ProcessTweakFlexbody();
}

m_context->seekNextLine();
Expand Down Expand Up @@ -332,7 +336,6 @@ void AddonPartUtility::ProcessTweakWheel()
{
ROR_ASSERT(m_context->getTokKeyword() == "addonpart_tweak_wheel"); // also asserts !EOF and TokenType::KEYWORD

// 'addonpart_tweak_wheel <wheel ID> <rim mesh> <tire radius> <rim radius>'
if (m_context->isTokFloat(1) && m_context->isTokString(2))
{
const int wheel_id = (int)m_context->getTokFloat(1);
Expand Down Expand Up @@ -380,7 +383,6 @@ void AddonPartUtility::ProcessTweakNode()
{
ROR_ASSERT(m_context->getTokKeyword() == "addonpart_tweak_node"); // also asserts !EOF and TokenType::KEYWORD

// Data of 'addonpart_tweak_node <nodenum> <posX> <posY> <posZ>'
if (m_context->isTokFloat(1) && m_context->isTokFloat(1) && m_context->isTokFloat(2) && m_context->isTokFloat(3))
{
NodeNum_t nodenum = (NodeNum_t)m_context->getTokFloat(1);
Expand Down Expand Up @@ -421,3 +423,114 @@ void AddonPartUtility::ProcessTweakNode()
LOG(fmt::format("[RoR|Addonpart] WARNING: file '{}', element '{}': bad arguments", m_addonpart_entry->fname, m_context->getTokKeyword()));
}
}

void AddonPartUtility::ProcessTweakFlexbody()
{
ROR_ASSERT(m_context->getTokKeyword() == "addonpart_tweak_flexbody"); // also asserts !EOF and TokenType::KEYWORD

// TBD: add `null` token type to GenericDocument, so these params can be made optional
if (m_context->isTokFloat(1) && // ID
m_context->isTokFloat(2) && m_context->isTokFloat(3) && m_context->isTokFloat(4) && // offset
m_context->isTokFloat(5) && m_context->isTokFloat(6) && m_context->isTokFloat(7) && // rotation
m_context->isTokString(8)) // media
{
const int flexbody_id = (int)m_context->getTokFloat(1);
if (!m_tuneup->isFlexbodyProtected(flexbody_id))
{
if (m_tuneup->flexbody_tweaks.find(flexbody_id) == m_tuneup->flexbody_tweaks.end())
{
TuneupFlexbodyTweak data;
data.tft_origin = m_addonpart_entry->fname;
data.tft_flexbody_id = flexbody_id;
data.tft_offset.x = m_context->getTokFloat(2);
data.tft_offset.y = m_context->getTokFloat(3);
data.tft_offset.z = m_context->getTokFloat(4);
data.tft_rotation.x = m_context->getTokFloat(5);
data.tft_rotation.y = m_context->getTokFloat(6);
data.tft_rotation.z = m_context->getTokFloat(7);
data.tft_media = m_context->getTokString(8);
m_tuneup->flexbody_tweaks.insert(std::make_pair(flexbody_id, data));

LOG(fmt::format("[RoR|Addonpart] INFO: file '{}', element '{}': tweaking flexbody {}"
" with params {{ offsetX={}, offsetY={}, offsetZ={}, rotX={}, rotY={}, rotZ={}, media={} }}",
m_addonpart_entry->fname, m_context->getTokKeyword(), flexbody_id,
data.tft_offset.x, data.tft_offset.y, data.tft_offset.z,
data.tft_rotation.x, data.tft_rotation.y, data.tft_rotation.z, data.tft_media[0]));
}
else if (m_tuneup->flexbody_tweaks[flexbody_id].tft_origin != m_addonpart_entry->fname)
{
m_tuneup->flexbody_tweaks.erase(flexbody_id);

LOG(fmt::format("[RoR|Addonpart] INFO: file '{}', element '{}': Conflict of tweaks at flexbody '{}', addon parts '{}' and '{}'",
m_addonpart_entry->fname, m_context->getTokKeyword(), flexbody_id,
m_tuneup->flexbody_tweaks[flexbody_id].tft_origin, m_addonpart_entry->fname));
}
}
else
{
LOG(fmt::format("[RoR|Addonpart] INFO: file '{}', element '{}': skipping flexbody '{}' because it's marked PROTECTED",
m_addonpart_entry->fname, m_context->getTokKeyword(), (int)m_context->getTokFloat(1)));
}
}
else
{
LOG(fmt::format("[RoR|Addonpart] WARNING: file '{}', element '{}': bad arguments", m_addonpart_entry->fname, m_context->getTokKeyword()));
}
}

void AddonPartUtility::ProcessTweakProp()
{
ROR_ASSERT(m_context->getTokKeyword() == "addonpart_tweak_prop"); // also asserts !EOF and TokenType::KEYWORD

// TBD: add `null` token type to GenericDocument, so these params can be made optional
if (m_context->isTokFloat(1) && // ID
m_context->isTokFloat(2) && m_context->isTokFloat(3) && m_context->isTokFloat(4) && // offset
m_context->isTokFloat(5) && m_context->isTokFloat(6) && m_context->isTokFloat(7) && // rotation
m_context->isTokString(8)) // media
{
const int prop_id = (int)m_context->getTokFloat(1);
if (!m_tuneup->isFlexbodyProtected(prop_id))
{
if (m_tuneup->prop_tweaks.find(prop_id) == m_tuneup->prop_tweaks.end())
{
TuneupPropTweak data;
data.tpt_origin = m_addonpart_entry->fname;
data.tpt_prop_id = prop_id;

data.tpt_offset.x = m_context->getTokFloat(2);
data.tpt_offset.y = m_context->getTokFloat(3);
data.tpt_offset.z = m_context->getTokFloat(4);
data.tpt_rotation.x = m_context->getTokFloat(5);
data.tpt_rotation.y = m_context->getTokFloat(6);
data.tpt_rotation.z = m_context->getTokFloat(7);
data.tpt_media[0] = m_context->getTokString(8);
if (m_context->isTokString(9)) data.tpt_media[1] = m_context->getTokString(9); // <== Optional Media2 is specific for prop
m_tuneup->prop_tweaks.insert(std::make_pair(prop_id, data));

LOG(fmt::format("[RoR|Addonpart] INFO: file '{}', element '{}': tweaking prop {}"
" with params {{ media1={}, offsetX={}, offsetY={}, offsetZ={}, rotX={}, rotY={}, rotZ={}, media2={} }}",
m_addonpart_entry->fname, m_context->getTokKeyword(), prop_id, data.tpt_media[0],
data.tpt_offset.x, data.tpt_offset.y, data.tpt_offset.z,
data.tpt_rotation.x, data.tpt_rotation.y, data.tpt_rotation.z,
data.tpt_media[1]));
}
else if (m_tuneup->prop_tweaks[prop_id].tpt_origin != m_addonpart_entry->fname)
{
m_tuneup->prop_tweaks.erase(prop_id);

LOG(fmt::format("[RoR|Addonpart] INFO: file '{}', element '{}': Conflict of tweaks at prop '{}', addon parts '{}' and '{}'",
m_addonpart_entry->fname, m_context->getTokKeyword(), prop_id,
m_tuneup->prop_tweaks[prop_id].tpt_origin, m_addonpart_entry->fname));
}
}
else
{
LOG(fmt::format("[RoR|Addonpart] INFO: file '{}', element '{}': skipping prop '{}' because it's marked PROTECTED",
m_addonpart_entry->fname, m_context->getTokKeyword(), (int)m_context->getTokFloat(1)));
}
}
else
{
LOG(fmt::format("[RoR|Addonpart] WARNING: file '{}', element '{}': bad arguments", m_addonpart_entry->fname, m_context->getTokKeyword()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,14 @@ class AddonPartUtility
void ProcessManagedMaterial();
void ProcessProp();
void ProcessFlexbody();
void ProcessTweakWheel();
void ProcessTweakNode();
void ProcessTweakFlexbody();
void ProcessTweakProp();

// Helpers of `ResolveUnwantedAndTweakedElements()`, they expect `m_context` to be in position:
void ProcessUnwantedProp();
void ProcessUnwantedFlexbody();
void ProcessTweakWheel();
void ProcessTweakNode();

// Shared state:
GenericDocumentPtr m_document;
Expand Down
4 changes: 2 additions & 2 deletions source/main/resources/tuneup_fileformat/TuneupFileFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ Ogre::Vector3 RoR::TuneupUtil::getTweakedPropRotation(CacheEntryPtr& tuneup_entr
if (itor == tuneup_entry->tuneup_def->prop_tweaks.end())
return orig_val;

Ogre::Vector3 retval = itor->second.tpt_rot;
Ogre::Vector3 retval = itor->second.tpt_rotation;
ROR_ASSERT(!isnan(retval.x));
ROR_ASSERT(!isnan(retval.y));
ROR_ASSERT(!isnan(retval.z));
Expand Down Expand Up @@ -268,7 +268,7 @@ Ogre::Vector3 RoR::TuneupUtil::getTweakedFlexbodyRotation(CacheEntryPtr& tuneup_
if (itor == tuneup_entry->tuneup_def->flexbody_tweaks.end())
return orig_val;

Ogre::Vector3 retval = itor->second.tft_rot;
Ogre::Vector3 retval = itor->second.tft_rotation;
ROR_ASSERT(!isnan(retval.x));
ROR_ASSERT(!isnan(retval.y));
ROR_ASSERT(!isnan(retval.z));
Expand Down
Loading

0 comments on commit 9551d05

Please sign in to comment.