port 2V2-d.2: Granny runtime on libgr2, main character model animates
Implement the Granny SDK 2.11 API the client uses on top of libgr2 (platform/EterGrnLib/GrannyRuntime.cpp, shim granny.h declared from the SDK header): file sections, type-definition vertex conversion, material textures by Usage, mesh/bone bindings, deformer, control clock/loop/ease and weighted SRT sampling. Port EterGrnLib (LODController, Material, Mesh, Model, ModelInstance*, Motion, Thing, ThingInstance, Util) plus EterLib GrpObjectInstance/GrpCollisionObject/CollisionData verbatim and drop their platform skeletons and pending stand-ins; register the gr2 resource factory; vertex/index buffers are CPU-side until the 2V2-e render adapter. app.UpdateGame/RenderGame now run 40250's bodies, reaching the CPythonApplication members through their singletons (the platform has no app object); CPythonGraphic joins GameSingletons in member order, and GetMousePosition reads the host cursor. port.login_flow asserts the main instance's PART_MAIN model has meshes, its diffuse image loaded and the WAIT motion moves the bones between frames; offline and live pass, port_gate macos PASS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5266b00c6e
commit
668f48d6ec
@@ -47,6 +47,10 @@
|
||||
#include "UserInterface/StdAfx.h"
|
||||
#include "UserInterface/PythonCharacterManager.h"
|
||||
#include "UserInterface/InstanceBase.h"
|
||||
#include "EterGrnLib/StdAfx.h"
|
||||
#include "EterGrnLib/LODController.h"
|
||||
#include "EterGrnLib/ModelInstance.h"
|
||||
#include "EterGrnLib/Model.h"
|
||||
#include "port_login_flow_server.h"
|
||||
|
||||
#include <memory>
|
||||
@@ -315,6 +319,33 @@ int main(int argc, char** argv)
|
||||
CHECK(main_instance != nullptr);
|
||||
CHECK(live || (main_instance && main_instance->GetRace() == 0));
|
||||
CHECK(count_syserr("TPacketGCCharacterAdditionalInfo") == 0);
|
||||
// (批次 2V2-d.2) SetRace/SetShape loaded the body .gr2 through the Granny runtime into PART_MAIN, and
|
||||
// game.GameWindow's OnUpdate/OnRender (app.UpdateGame/RenderGame) play the WAIT motion: the
|
||||
// sampled bone matrices change between frames.
|
||||
CGrannyLODController* lod = main_instance ?
|
||||
main_instance->GetGraphicThingInstanceRef().GetLODControllerPointer(CRaceData::PART_MAIN) : nullptr;
|
||||
CGrannyModelInstance* model_instance = lod ? lod->GetModelInstance() : nullptr;
|
||||
CGrannyModel* model = model_instance ? model_instance->GetModel() : nullptr;
|
||||
CHECK(model && model->GetMeshCount() > 0);
|
||||
// The material's diffuse map resolved through GrannyGetMaterialTextureByType to a loaded image.
|
||||
CGrannyMaterialPalette* palette = model ? const_cast<CGrannyMaterialPalette*>(&model->GetMaterialPalette()) : nullptr;
|
||||
CHECK(palette && palette->GetMaterialCount() > 0 && palette->GetMaterialRef(0).GetImagePointer(0));
|
||||
const int bone_count = model ? model->GetGrannyModelPointer()->Skeleton->BoneCount : 0;
|
||||
CHECK(bone_count > 1);
|
||||
auto bones = [&] {
|
||||
std::vector<float> out;
|
||||
for (int i = 0; i < bone_count; ++i)
|
||||
{
|
||||
const float* m = model_instance->GetBoneMatrixPointer(i);
|
||||
out.insert(out.end(), m, m + 16);
|
||||
}
|
||||
return out;
|
||||
};
|
||||
if (bone_count > 1)
|
||||
{
|
||||
const std::vector<float> before = bones();
|
||||
CHECK(pump_until(3, [&] { return bones() != before; }));
|
||||
}
|
||||
}
|
||||
if (server)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user