2V3-a: walk with the keyboard through the ported player chain
PythonPlayer, PythonPlayerInput{,Keyboard,Mouse}, PythonPlayerEventHandler,
PythonPlayerSkill, PythonPlayerModule and GameType are verbatim copies; the
`player` stub module and the pending PythonPlayer/GameType stand-ins are gone.
Unported callees (CPythonSkill, CItemData, CItemManager, CPythonItem, ...) are
pending stubs. 64-bit fixes: emotion icon handles use Py_BuildPointer, and
PyDict_Next takes Py_ssize_t.
The actor did not move because GrannyUpdateModelMatrix passed the model matrix
through. Walk/run motions use constant root-motion extraction
(AccumulationFlags=AccumulationExtracted, LoopTranslation e.g. (0,-300,0) for
the warrior run, same as the .msa Accumulation). libgr2 now reads both fields
from TrackGroups[0], and the runtime moves by LoopTranslation over each
control's local-clock span, blended by control weight. VDA extraction is not
implemented.
port.login_flow presses DIK_UP; the actor walks more than 100 cm, and the fake
server parses CG packets and sees CG_MOVE FUNC_MOVE, then FUNC_WAIT at the new
position. port.login_live against the real server walked 132 cm.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
157f7c3bb4
commit
ff0983d3c8
@@ -131,6 +131,10 @@ struct Animation {
|
||||
float oversampling = 1.0f;
|
||||
int32_t track_group_count = 0;
|
||||
std::vector<TextTrack> text_tracks; // TrackGroups[0].TextTracks
|
||||
// TrackGroups[0].AccumulationFlags / LoopTranslation(root motion:
|
||||
// 1 = AccumulationExtracted,4 = AccumulationIsVDA)。
|
||||
int32_t accumulation_flags = 0;
|
||||
float loop_translation[3] = {0.0f, 0.0f, 0.0f};
|
||||
std::vector<BoneTrack> tracks;
|
||||
// t 处每个 track 的局部 4x4(granny_transform 组合语义,行主序)。
|
||||
// out 按 tracks 顺序;bone_index 见各 track。
|
||||
|
||||
@@ -109,6 +109,17 @@ bool File::Impl::extract_animation(Ref anim_obj, Ref anim_type, const Skeleton*
|
||||
out.track_group_count = int32_t(groups.size());
|
||||
const auto& tgms = parse_type(mTG->ref_type);
|
||||
|
||||
// TrackGroups[0].AccumulationFlags (Int32) + LoopTranslation (Real32[3])
|
||||
if (!groups.empty() && groups[0].valid()) {
|
||||
if (const TypeMember* m = find_member(tgms, "AccumulationFlags"))
|
||||
out.accumulation_flags = rd_i32(member_slot(groups[0], *m));
|
||||
if (const TypeMember* m = find_member(tgms, "LoopTranslation")) {
|
||||
Ref r = member_slot(groups[0], *m);
|
||||
for (int i = 0; i < 3; ++i)
|
||||
out.loop_translation[i] = rd_f32(Ref{r.section, r.offset + uint32_t(i) * 4u});
|
||||
}
|
||||
}
|
||||
|
||||
// TrackGroups[0].TextTracks: RefToArray text_track{String Name; RefToArray Entries(
|
||||
// text_track_entry{Real32 TimeStamp; String Text})}(motion event 用)
|
||||
if (!groups.empty() && groups[0].valid())
|
||||
|
||||
Reference in New Issue
Block a user