Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions Code/Converter/BlueprintConverter/BlueprintConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "ObjectDatabase/DatabaseConfig.hpp"
#include "ObjectDatabase/ProgCounter.hpp"

#include "Converter/Entity/ControllerParser.hpp"
#include "Converter/Entity/ControllerTransform.hpp"
#include "Converter/ConvertSettings.hpp"
#include "Converter/MtlFileWriter.hpp"

Expand Down Expand Up @@ -259,20 +261,34 @@ void BlueprintConv::ConvertToModel(
SMBlueprint::AddObjectFunction v_add_obj_func = BlueprintConv::GetAddObjectFunction();
SMBlueprint* v_pBlueprint = nullptr;

// Reuse parsed DOM for controller presets to avoid double-parsing
const bool v_needPresets = BlueprintConverterSettings::ApplyControllerPresets;
simdjson::dom::document v_bpDoc;
simdjson::dom::document* v_pDocOut = v_needPresets ? &v_bpDoc : nullptr;

if (pCustomGame)
{
SMModCustomGameSwitch<true, false> v_content_switch;
v_content_switch.MergeContent(pCustomGame);

v_pBlueprint = SMBlueprint::FromFileWithStatus(bp_path, v_add_obj_func, error);
v_pBlueprint = SMBlueprint::FromFileWithStatus(bp_path, v_add_obj_func, error, v_pDocOut);
}
else
{
v_pBlueprint = SMBlueprint::FromFileWithStatus(bp_path, v_add_obj_func, error);
v_pBlueprint = SMBlueprint::FromFileWithStatus(bp_path, v_add_obj_func, error, v_pDocOut);
}

if (v_pBlueprint)
{
if (v_needPresets && !error)
{
const auto v_bpRoot = v_bpDoc.root();
ControllerPresetData v_presetData = ControllerParser::ExtractPresets(v_bpRoot);
auto v_bodyGraph = ControllerParser::BuildBodyGraph(
v_bpRoot, v_presetData, v_pBlueprint->m_childToBodyIndex);
ControllerTransform::Apply(v_pBlueprint, v_bodyGraph, v_pBlueprint->m_childToBodyIndex);
}

BlueprintConv::WriteToFileInternal(v_pBlueprint, bp_name, error);

//Since all the sorted groups are attached to the blueprint, the blueprint takes care of all the allocated memory
Expand Down
1 change: 1 addition & 0 deletions Code/Converter/ConvertSettings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct TileConverterSettings
struct BlueprintConverterSettings
{
inline static int SeparationType = 0;
inline static bool ApplyControllerPresets = false;

private:
BlueprintConverterSettings() = default;
Expand Down
2 changes: 1 addition & 1 deletion Code/Converter/Entity/Block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ void SMBlock::WriteObjectToFile(
Model v_blockModel;
FillCustomCube(v_blockModel, m_size / 2.0f, m_position, m_parent->m_tiling);

const glm::mat4 v_blockTransform = transform * this->GetTransformMatrix();
const glm::mat4 v_blockTransform = transform * m_preTransform * this->GetTransformMatrix();
v_blockModel.WriteToFile(v_blockTransform, offset, file, this);

ProgCounter::ProgressValue++;
Expand Down
8 changes: 6 additions & 2 deletions Code/Converter/Entity/Blueprint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,13 @@ SMBlueprint* SMBlueprint::FromFile(
SMBlueprint* SMBlueprint::FromFileWithStatus(
const std::wstring_view& path,
SMBlueprint::AddObjectFunction v_addObjFunc,
ConvertError& error)
ConvertError& error,
simdjson::dom::document* pDocOut)
{
ProgCounter::SetState(ProgState::ParsingBlueprint, 0);

simdjson::dom::document v_bp_doc;
simdjson::dom::document v_localDoc;
simdjson::dom::document& v_bp_doc = pDocOut ? *pDocOut : v_localDoc;
if (!JsonReader::LoadParseSimdjsonC(path, v_bp_doc, simdjson::dom::element_type::OBJECT))
{
error.setError(1, "Couldn't read the specified blueprint file. Possible reason: Invalid file, Parse error, Invalid path");
Expand Down Expand Up @@ -408,6 +410,7 @@ void SMBlueprint::LoadBodiesWithCounter(const simdjson::dom::element& v_blueprin

for (const auto v_child : v_childs_array)
{
m_childToBodyIndex[m_objectIndex] = m_bodyIndex;
this->LoadChild(v_child);

ProgCounter::ProgressValue++;
Expand Down Expand Up @@ -447,6 +450,7 @@ void SMBlueprint::LoadBodies(const simdjson::dom::element& pJson)

for (const auto v_child : v_childs_array.get_array().value_unsafe())
{
m_childToBodyIndex[m_objectIndex] = m_bodyIndex;
this->LoadChild(v_child);
m_objectIndex++;
}
Expand Down
12 changes: 9 additions & 3 deletions Code/Converter/Entity/Blueprint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "Utils/clr_include.hpp"
#include "Utils/Json.hpp"

#include <unordered_map>

SM_UNMANAGED_CODE

class SMBlueprint final : public SMEntity
Expand All @@ -32,7 +34,7 @@ class SMBlueprint final : public SMEntity
static SMBlueprint* LoadAutomatic(const std::string_view& str, const glm::vec3& pos, const glm::quat& rot);
static SMBlueprint* FromFile(const std::wstring_view& path, const glm::vec3& pos, const glm::quat& rot);
//Used by blueprint converter as it reports the conversion status
static SMBlueprint* FromFileWithStatus(const std::wstring_view& path, AddObjectFunction v_addObjFunc, ConvertError& v_error);
static SMBlueprint* FromFileWithStatus(const std::wstring_view& path, AddObjectFunction v_addObjFunc, ConvertError& v_error, simdjson::dom::document* pDocOut = nullptr);
static SMBlueprint* FromJsonString(const std::string_view& json_str, const glm::vec3& pos, const glm::quat& rot);

EntityType Type() const override;
Expand All @@ -41,6 +43,8 @@ class SMBlueprint final : public SMEntity
std::size_t GetAmountOfObjects() const override;
void CalculateCenterPoint(glm::vec3& outInput) const override;

static glm::vec3 JsonToVector(const simdjson::simdjson_result<simdjson::dom::element>& vec_json);

/*
This vector contains blocks, parts and joints
When in blueprint converter mode, this vector only stores bodies
Expand All @@ -52,8 +56,6 @@ class SMBlueprint final : public SMEntity

static void AddObject_Default(SMBlueprint* self, SMEntity* pEntity);

static glm::vec3 JsonToVector(const simdjson::simdjson_result<simdjson::dom::element>& vec_json);

void LoadChild(const simdjson::dom::element& v_child);
void LoadJoint(const simdjson::dom::element& v_jnt);

Expand All @@ -65,6 +67,10 @@ class SMBlueprint final : public SMEntity

std::size_t m_objectIndex;
std::size_t m_bodyIndex;

public:
// child index -> body index (for controller presets)
std::unordered_map<std::size_t, std::size_t> m_childToBodyIndex;
};

SM_MANAGED_CODE
17 changes: 17 additions & 0 deletions Code/Converter/Entity/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,21 @@ void SMBody::CalculateCenterPoint(glm::vec3& outInput) const
std::size_t SMBody::GetAmountOfObjects() const
{
return m_objects.size();
}

void SMBody::ApplyPreTransformByBodyMap(
const std::unordered_map<std::size_t, glm::mat4>& bodyTransforms,
const std::unordered_map<std::size_t, std::size_t>& childToBodyMap)
{
for (SMEntity* v_pEntity : m_objects)
{
const std::size_t v_entityIdx = v_pEntity->GetIndex();
const auto v_bodyIt = childToBodyMap.find(v_entityIdx);
if (v_bodyIt == childToBodyMap.end()) continue;

const auto v_transformIt = bodyTransforms.find(v_bodyIt->second);
if (v_transformIt == bodyTransforms.end()) continue;

v_pEntity->SetPreTransform(v_transformIt->second);
}
}
6 changes: 6 additions & 0 deletions Code/Converter/Entity/Body.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "UStd/UnmanagedString.hpp"
#include "UStd/UnmanagedVector.hpp"

#include <unordered_map>

SM_UNMANAGED_CODE

class SMBody : public SMEntity
Expand All @@ -29,6 +31,10 @@ class SMBody : public SMEntity
void CalculateCenterPoint(glm::vec3& outInput) const override;
std::size_t GetAmountOfObjects() const override;

void ApplyPreTransformByBodyMap(
const std::unordered_map<std::size_t, glm::mat4>& bodyTransforms,
const std::unordered_map<std::size_t, std::size_t>& childToBodyMap);

private:
std::vector<SMEntity*> m_objects;
std::string m_bodyName;
Expand Down
26 changes: 26 additions & 0 deletions Code/Converter/Entity/ControllerData.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include "Utils/GlmUnmanaged.hpp"
#include "Utils/clr_include.hpp"

#include <unordered_map>

SM_UNMANAGED_CODE

struct ControllerPresetData
{
// joint_id -> angle in degrees (negated if reverse)
std::unordered_map<std::size_t, float> bearingAngles;
// controller_id -> extension in notches
std::unordered_map<std::size_t, float> pistonSettings;
};

struct JointConnection
{
std::size_t parentBodyIdx;
std::size_t childBodyIdx;
glm::mat4 localTransform{ 1.0f }; // identity if no preset
bool hasPreset = false;
};

SM_MANAGED_CODE
Loading