-
Notifications
You must be signed in to change notification settings - Fork 72
Plat 11607 modular ship assembly #62
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
Merged
Merged
Changes from all commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
a0d04a0
Refactor IEveSpaceObjectChild interface into a base class
filipppavlov cf19ad9
Add the important files
filipppavlov ce89584
Format files
filipppavlov 28e6890
Use property to access the part tag
filipppavlov 3173b93
Potential fix for pull request finding
filipppavlov 9384303
Refactor IEveSpaceObjectChild interface into a base class
filipppavlov 98f1653
Add the important files
filipppavlov d125679
Format files
filipppavlov 6fc4d0e
Use property to access the part tag
filipppavlov 5d1cfe0
Potential fix for pull request finding
filipppavlov 8d7e70e
Rebase to main
filipppavlov 8d7558c
Merge branch 'space-object-child-base-class' of https://github.com/ca…
filipppavlov af391b2
Modular object building wip
filipppavlov dad3a52
Transform locators
filipppavlov b09f06f
Merge remote-tracking branch 'origin/main' into PLAT-11607-modular-sh…
Ikreb1 2ea14a2
Merge remote-tracking branch 'origin/main' into PLAT-11607-modular-sh…
Ikreb1 7b37392
unregister child assert allows get parent nullptr as well
Ikreb1 5c7fd6c
add invalid part tag for error messages
Ikreb1 6137ec7
keep locator order on remove
Ikreb1 8588595
build shapeEllipsoid on modifier deletion like how boundingSphere was…
Ikreb1 4aa827e
apply boundingsphere transform correctly on SetTransform
Ikreb1 ed89d23
Set the part tag for the child when adding children
Ikreb1 7f52c36
Fix issue where boundingsphere that fully encapsulates a smaller boun…
Ikreb1 d8b67a4
Merge branch 'main' into PLAT-11607-modular-ship-assembly
Ikreb1 6f2ab51
handle layout part tag range support and fix issue with damage locato…
Ikreb1 42e4e49
apply feedback from copilot review
Ikreb1 38f59ae
Update trinity/Eve/SpaceObject/Utils/EveLocatorSets.cpp
Ikreb1 d4aef48
expland blue class macro to fix clang formatting
Ikreb1 423bc8f
remove range based part tag for modular
Ikreb1 7043aa3
Add documentation to modular ship assembly
Ikreb1 9c0e870
Update trinity/Eve/SpaceObject/Children/EveChildPartData_Blue.cpp
Ikreb1 4651fb4
Add more documentation to modular ship assembly and separate EveModul…
Ikreb1 50e8f0b
fixup comment
Ikreb1 b4c4c4d
Merge remote-tracking branch 'origin/main' into PLAT-11607-modular-sh…
Ikreb1 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| :orphan: | ||
|
|
||
| Modular ship assembly | ||
| ===================== | ||
|
|
||
| A modular space object is a single ``EveSpaceObject2`` assembled at runtime from multiple SOF | ||
| hulls ("parts"), created via ``CreateModularObject`` and edited through the transient | ||
| ``EveModularObjectModifier`` session object. Persistent per-part state lives in | ||
| ``EveChildPartData``, an effect child on the object itself, so a saved or handed-off object | ||
| carries everything needed to reopen an edit session with ``ModifyModularObject``. | ||
|
|
||
| This page only describes the cross-cutting flow that no single file shows. API contracts live | ||
| with the API: the headers (``EveModularObjectModifier.h``, ``EveChildPartData.h``, ``EveSOF.h``) and the python docstrings on | ||
| ``trinity.CreateModularObject`` and the modifier methods. Beyond the usage example below, | ||
| values and signatures are deliberately not repeated here. | ||
|
|
||
| Python example | ||
| -------------- | ||
|
|
||
| Condensed from ``packages/trinity/tests/test_modular.py``, which exercises the full API and is | ||
| the authoritative reference for behavior. The modifier edits the object immediately, but | ||
| culling bounds are only committed by ``ApplyBounds``, or by dropping the last reference to the | ||
| modifier, which the example relies on. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| import trinity | ||
|
|
||
| IDENTITY_ROT = (0, 0, 0, 1) | ||
| UNIT_SCALE = (1, 1, 1) | ||
|
|
||
| sof = trinity.EveSOF() | ||
| sof.dataMgr.LoadData('res:/dx9/model/spaceobjectfactory/data.red') | ||
|
|
||
| # Create an empty modular object. The faction/race arguments seed the | ||
| # defaults used when AddHull is passed empty strings. | ||
| ship, modifier = trinity.CreateModularObject(sof, 'somefaction', 'somerace') | ||
|
|
||
| core = modifier.AddHull('some_hull', '', '', (0, 0, 0), IDENTITY_ROT, UNIT_SCALE) | ||
| wing = modifier.AddHull('other_hull', 'somefaction', 'somerace', | ||
| (30, 0, 0), IDENTITY_ROT, UNIT_SCALE) | ||
| if wing == trinity.GetInvalidPartTag(): | ||
| raise RuntimeError('hull failed to build') | ||
|
|
||
| # Non-SOF parts come from a space object child resource. | ||
| beacon = modifier.AddChild('res:/model/somechild.red', (0, 50, 0), IDENTITY_ROT, UNIT_SCALE) | ||
|
|
||
| modifier.SetTransform(wing, (-30, 0, 0), IDENTITY_ROT, UNIT_SCALE) | ||
| modifier.Remove(beacon) # KeyError on an unknown or already-removed tag | ||
|
|
||
| del modifier # last reference dropped: bounding sphere and shape ellipsoid commit here | ||
|
|
||
| # Part tags stay valid across sessions: EveChildPartData persists them on the | ||
| # object, so a saved/reloaded object reopens the same way. | ||
| modifier = trinity.ModifyModularObject(ship, sof) | ||
| assert modifier.GetPosition(wing) == (-30, 0, 0) | ||
| del modifier | ||
|
|
||
| Part-tag propagation | ||
| -------------------- | ||
|
|
||
| A part tag (``EveSpaceObjectChild::PartTag``, sentinels documented in ``EveSpaceObjectChild.h`` | ||
| and ``EveModularObjectModifier.h``) identifies everything belonging to one part. It flows: | ||
|
|
||
| 1. **Allocation**: ``EveModularObjectModifier::AllocatePartId`` (``EveModularObjectModifier.cpp``) takes | ||
| the max over ``EveChildPartData::GetUnusedPartID`` and the tags of existing effect children. | ||
| 2. **SOF build**: ``EveSOF::BuildChild`` (``EveSOF.cpp``) stamps the tag on every container and | ||
| child it creates; nested layout placements flow it through ``EveSOF::SetupLayout`` / | ||
| ``EveSOF::CreatePlacement``. | ||
| 3. **Locators**: ``EveSOF::SetupLocatorSets`` stamps ``partTag`` on each generated locator | ||
| (``EveSOFDataMgr::LocatorDirectionData`` converts to ``Locator`` preserving it), then merges | ||
| into the object via ``EveSpaceObject2::MergeToLocatorSet``. The merged view built by | ||
| ``EveSpaceObject2::EnsureChildLocatorMerged`` preserves per-locator tags. | ||
| 4. **Mesh instances**: instanced meshes are shared across parts, so the tag is per *instance*, | ||
| not per child. Each ``EveChildInstancedMeshes::Mesh`` carries a ``partTags`` vector parallel | ||
| to the instance data (written in ``AddMesh``, consumed by ``RemoveInstancesByPartTag``). The | ||
| child's own ``m_partTag`` is meaningless for instanced meshes. | ||
| 5. **Effect children**: ``EveSpaceObjectChild::SetPartTag`` propagates through container | ||
| overrides (``EveChildContainer::SetPartTag`` etc.), and ``EveSpaceObjectChild::RegisterChild`` | ||
| copies the parent's tag onto newly attached children. | ||
|
|
||
| Locator lifecycle during editing | ||
| -------------------------------- | ||
|
|
||
| - **AddHull**: locators from every hull merge into the object's sets *by set name*, with no | ||
| renaming or prefixing (``EveSpaceObject2::MergeToLocatorSet`` appends to an existing same-named | ||
| set). Parts are distinguishable within a set only by ``partTag``. | ||
| - **Remove**: locators are stripped from every set by exact ``partTag`` match, mesh instances via | ||
| ``RemoveInstancesByPartTag``, effect children by tag; accumulated impact damage is cleared. | ||
| - **SetTransform**: locators of the part are re-derived in place (position through | ||
| inverse-old-transform then new-transform, direction and scale by delta), and the part's stored | ||
| bounding sphere is re-transformed the same way. See | ||
| ``EveModularObjectModifier::SetTransform`` (``EveModularObjectModifier.cpp``). | ||
| - **Damage locators / impact overlay**: the impact overlay allocates per-damage-locator slots, so | ||
| its count must track the merged ``DAMAGE_LOCATOR_SET_NAME`` locator set. ``UpdateImpactOverlayLocatorCount`` | ||
| re-syncs it after AddHull/Remove; a stale count would index locators that no longer exist. | ||
| - Any structural edit calls ``EveSpaceObject2::InvalidateMergedLocators`` so the merged view is | ||
| rebuilt lazily. | ||
|
|
||
| Gotchas | ||
| ------- | ||
|
|
||
| - A modular object with zero parts (or before ``ApplyBounds``/modifier destruction ever ran) has | ||
| a zero-radius bounding sphere: ``EveSpaceObject2::UpdateVisibility`` skips the mesh-visibility | ||
| test and ``EveSpaceObject2::IsVisible`` culls it at any distance, so it never renders. | ||
| - Culling volumes are only pushed to the object by ``EveModularObjectModifier::ApplyBounds`` (the | ||
| destructor calls it too). Editing without applying leaves the object rendering with stale | ||
| bounds. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| // Copyright © 2026 CCP ehf. | ||
|
|
||
| #include "StdAfx.h" | ||
| #include "EveChildPartData.h" | ||
| #include <numeric> | ||
|
|
||
|
|
||
| EveChildPartData::EveChildPartData( IRoot* ) | ||
| { | ||
| } | ||
|
|
||
| EveSpaceObjectChild::PartTag EveChildPartData::GetUnusedPartID() const | ||
| { | ||
| return std::accumulate( m_parts.begin(), m_parts.end(), 1u, []( EveSpaceObjectChild::PartTag maxId, const PartData& part ) { | ||
| return std::max( maxId, part.partId + 1 ); | ||
| } ); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.