The insignia normal array was declared with the vertex limit, filled in by
face index, and read by vertex index. An insignia with more than 81 faces
therefore wrote past the array, into the following insignia or, for the
sixth and final slot, past the insignia list into the rest of the
polymodel. And the renderer lit each vertex with the normal of whichever
face shared its index, or with a zero normal (ambient light only) when
there was no such face.
A normal belongs to a face, so size the array by the face limit and light
all three corners of each face with that face's normal.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Restore the original flag values that were consolidated in #7588. Since the flags are saved in the mission file as an integer, the original values must be preserved.
Since `MR_ATTACHED_MODEL` was removed in the original PR, that is renamed to `MR_EMPTY_SLOT6`.
The draw-distance cull for attached external weapon models checked
MR_ATTACHED_MODEL, but nothing has set that flag since commit
1ef7688fa1, so $Weapon Model Draw Distance: has been dead for years.
The check also needed the ship resolved from the render params' object
number, which is deliberately not set while weapon models render
(setting it would make model_render_queue clobber the explicitly
passed gatling model instance), and it compared against a depth
computed as if the weapon model's ship-local position were in world
space.
Carry the distance in model_render_params instead
(set_attached_model_draw_distance, negative = not an attached model),
set by ship_render_weapon_models from the ship's tabled value. When
set, model_render_queue measures depth from the eye position expressed
in the parent's frame (model_draw_list::get_view_position), which is
correct under the pushed parent transform, culls against the tabled
distance, and uses that same corrected depth for detail level
selection -- previously attached weapon models picked their LOD from a
garbage depth (roughly the eye's distance from the world origin).
MR_ATTACHED_MODEL is removed; nothing else referenced it. The unused
flags are also removed and the remaining flags are consolidated.
Co-Authored-By: Claude Fable 5 <[email protected]>
w_bank: add a move constructor. object_copy_including_array_member
returns by value, and without a move constructor the return fell back
to the shallow copy constructor whenever NRVO was not applied (e.g.
MSVC debug builds), after which the local's destructor deleted the
freshly allocated arrays -- leaving the stored bank dangling and
double-deleting at model unload. Also add noexcept to the move
operations, replace the destructor call in move-assignment with
explicit delete[]s (using an object after its lifetime has ended is
undefined behavior), guard against self-move, and document that the
defaulted copy constructor is intentionally shallow for
object_copy_including_array_member's copy-then-replace pattern.
LuaThread: declare the defaulted move operations noexcept. This
exposed that LuaTable was not movable at all (its user-declared
destructor suppressed the implicit moves), so LuaThread's implicit
move spec was formally throwing -- a hard error on gcc 9, which
still requires the spec on a defaulted redeclaration to match the
implicit one. Restore LuaTable's rule of five and declare the
LuaValue and LuaFunction copy operations noexcept (they only copy a
shared_ptr, a raw pointer, and an enum), making the noexcept claims
hold throughout the hierarchy.
Co-Authored-By: Claude Fable 5 <[email protected]>
Replaces the copy-then-reset idiom with std::exchange in five
steal-and-reset move constructors and assignment operators.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Fix#4089, part 2:
- properly link special-point subsystems with -destroyed submodels, if such a relationship exists and a game_settings.tbl flag is set
- add some helper functions for -destroyed variants of submodels (and now subsystems)
Fix#4089, part 1:
- give the `my_replacement` and `i_replace` fields clearer names
- for submodels with the `Is_damaged` flag (representing -destroyed variants or debris), initialize them to blown-off (the true fix for #3078, fixing a regression introduced in the model instance refactor)
- roll back the de-parenting of live debris from #3089 (726ce953c7), because it was a wrong fix to the initialization bug and introduced its own subtle bug when positioning live debris
- roll back the `Can_move` flag skipping from #4138 (063d7afcfe), because it was another wrong fix to the initialization bug
- add some clarifying comments
* rename misleading variable check_again to never_check_again
The first element of collision_result means "never check again" per the
typedef comment, but was destructured as check_again (opposite meaning).
Rename to never_check_again to match the actual semantics and prevent
future confusion.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix data races in ship-weapon collision threading
Two thread-safety bugs in ship_weapon_check_collision, which runs on
worker threads:
1. update_danger_weapon() wrote to Ai_info[] (danger_weapon_objnum,
danger_weapon_signature) without synchronization. Multiple weapons
targeting the same ship would race on the same Ai_info entry.
2. Homing missile detonation logic wrote wp->lifeleft and
wp->weapon_flags directly on the Weapons[] global array.
Fix: defer both writes to the main-thread post-processing phase via
new flags in ship_weapon_collision_data. Also convert the collision
data from a 6-element tuple to a named struct for readability.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* fix data race in ship-ship collision submodel checking
ship_ship_check_collision() toggled pmi->submodel[].collision_checked
flags on the heavy ship's polymodel_instance to selectively enable/
disable submodel collision checks. When two collision pairs shared the
same heavy ship, worker threads would race on the same pmi entries.
Fix: add a collision_checked_override pointer to mc_info that lets
callers provide a thread-local array of collision_checked values.
model_collide() uses the override when set, falling back to the
pmi->submodel[] field otherwise. ship_ship_check_collision() now
builds a local SCP_vector<char> and passes it via the override,
completely avoiding writes to shared polymodel_instance state.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Ensure threads have spun down before continuing non-threaded execution
* address review feedback for ship-weapon collision threading
- postproc flag now accumulates incrementally instead of being OR'd
at the final return, ensuring all return paths respect it
- early return for predictive collisions now preserves the
should_update_danger_weapon flag in the collision data
- moved nprintf detonation debug print to the main-thread process
pass for thread safety
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* move collision_checked from pmi into mc_info for thread safety
collision_checked flags were transient per-collision-pass state that
didn't belong in the shared polymodel_instance. Now mc_info owns an
SCP_vector<char> that model_collide auto-initializes from pmi when
empty. All collision callers (ship-ship, asteroid, debris, prop)
updated to manipulate mc.collision_checked instead of pmi->submodel[].
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Convert to CV and spinup counter
* Update comment
---------
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Co-authored-by: BMagnu <[email protected]>
Add a useful function for getting a ship_info pointer from a ship registry entry. Also rename `ship_has_dock_bay` to `ship_has_hangar_bay` for clarity, since docking bays and docking points are not the same thing. Finally, add a `model_has_hangar_bay` function.
* Revert "Move insignia post-processing to model load"
This reverts commit 665d7145b6.
* Revert "Cleanup of old insignia stuff"
This reverts commit fdf98a1f3a.
* Revert "render insignias as decals"
This reverts commit 24cdeb3c95.
* Isolate reverts to insignias
* Fix oversight
* clang tidy
* Add flag to respect detailboxes in model collide checks
* Don't check detailboxes that are invisible for sunglare checks
* Use local coords
* Actualyl also run the check for cockpits & show ship
* Be less stupid
* Add parent / host input curves
* reorder some includes to allow particles access to ship.h
* Allow modular_curves to deal with functions returning optionals
* Add convenience function to return an optional from an objp and an instance type
* Add a bunch of particle curve inputs
* Fix internal linkage warning
* Add hitpoint and shield fraction (albeit limited to ships)
Add assertions to the model parsing macros to guard against accessing out-of-bounds memory. Patch the model parsing routines to avoid going out of bounds, even if the out of bounds situations are temporary and benign.
Several changes related to the volumetrics model fix:
1. Update the `model_load()` prototype with better parameter names, including a new `ErrorType` enum defined in pstypes.h
2. Update the `MIN`, `MAX`, and `CLAMP` macros, all of which were susceptible to performance issues because they duplicated their tokens. This could cause functions or calculations to be re-run unnecessarily. Since the codebase is now on C++17, `std::clamp()` can be used.
3. Update the rest of the codebase to fix any associated issues.
The recent cycle expansion PR (#6364) causes a CTD when change-ship-type is used. This PR fixes that crash by using `pm->n_guns` instead of 'MAX_SHIP_PRIMARY_BANKS' and clarifies the definition comment for the `pm->n_guns` to help avoid this kind of quandary in the furture.
Tested and works as expected.
1. Since we already handle `<all engines>` and `<all turrets>`, it's simple to extend this to all generic subsystems of any type
2. Add an `<all subsystems>` case for handling every subsystem on a ship
3. Add some compiler directives to enforce preconditions for subsystem type `#define`s
Model textures that are too long will cause a very unfriendly and hard-to-track down "ERANGE: String" error. The situation can be greatly improved by checking the string length ahead of time, printing a friendly Warning, and truncating the filename. This will alert the modder to the source of the problem while also allowing gameplay to continue.
* Remove old interpolate angles quick
* Remove old interpolate functions
These are no longer used.
* Add linear interpolate vm function
More clearing functions
* Add physics snapshot struct to silo interpolation
Two of these two functions require an object pointer, so they cannot be in physics_state.cpp
With doxygen documentation
* Try to placate Linux
* Address Feedback
* And update declaration, of course
* Attempt to appease linter
* Move replacement textures from ship to modelinstance
* Actually set pmi
* Fix texture replace in fred as well
* Fix bad indent
* incorporate feedback
* Add control_info driver sources
* Properly deal with cockpits and their 'objnum's
* Add driven animation sets to weapons and cockpits
* enumify objnums
1. make `check_ok_to_fire` return a boolean (like `check_los`)
2. make `check_ok_to_fire` and `check_los` both use a position argument since we don't need the whole turret
3. remove the redundant position prediction code from `ship_get_global_turret_gun_info` (since that needs to be a "pure" function) while making sure "share fire direction" still works
4. skip calculation of the vector in `ship_get_global_turret_gun_info` if we don't need it
5. move the position prediction code out of `aifft_rotate_turret` and into its own function
6. prune some gun position calculation calls since in most cases one will suffice
7. fix position "jitter" with weapon subsystem damage in missions that use gravity
8. `model_rotate_gun` now uses a nullptr position for a reset instead of an extra boolean argument
9. use a more efficient method to calculate gun barrel length
10. a couple variable name changes for clarity
* Add global to local for matrices
* Add lua integration
* Get Submodel from Submodel instance
* Add submodel functions
* Add model instance from submodel instance
* Fix index
* Fix copy paste error
Add `const` to the `mc_info` struct so its values aren't inadvertently overwritten. Tweak some of the collision code to prevent overwrites.
Also remove the `flak_muzzle_flash` declaration since that function no longer exists.
See title. There were some cascade effects, but the changes are mostly contained to the model code. The calls to `gr_render_model` and `g3_render_primitives` use `const_cast` because constifying that API would require a whole other PR.