Port of AVA2's CRenderTarget / GrpRenderTargetTexture / renderTarget module. The host gains an RGBA8 offscreen colour pass for D3D colour render targets; mt_preview shows wearable items on every allowed race and monsters with motions, reached by X+click in the inventory and shop and from the wiki. Player races are created as TYPE_PC so their parts exist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
82 lines
3.9 KiB
Markdown
82 lines
3.9 KiB
Markdown
# Model preview
|
||
|
||
Ported from AVA2's render-target window (`EterLib/CRenderTarget*`, `GrpRenderTargetTexture.*`, `UserInterface/CPythonRenderTargetModule.cpp`, `root/uirendertarget.py`). The preview shows:
|
||
- a wearable item on a character of every race that may wear it;
|
||
- a monster, with its motions.
|
||
|
||
It is client only; the server is not involved.
|
||
|
||
## Entry points
|
||
|
||
| Where | How |
|
||
|---|---|
|
||
| Inventory | hold X and left-click the item |
|
||
| NPC shop | hold X and left-click the item |
|
||
| Wiki detail | the "模型预览" line, on weapon / armor / costume rows that have a model, and on every monster |
|
||
|
||
Without X the original click path runs unchanged. The inventory wrapper chains onto `mt_mobile_inventory`'s, because `mt_preview` is installed after it. There is no touch entry other than the wiki.
|
||
|
||
## Window (`ScriptLib/ModelPreviewScript.inc`, module `mt_preview`)
|
||
|
||
### Item mode
|
||
- `ItemSpec(vnum)` accepts:
|
||
- a weapon other than an arrow → `SetWeapon`;
|
||
- a body armor or a body costume → `SetArmor`;
|
||
- a hair costume → `SetHair`, which reads value3.
|
||
- The races are those not excluded by `ITEM_ANTIFLAG_{MALE,FEMALE,WARRIOR,ASSASSIN,SURA,SHAMAN}`, ordered warrior, assassin, sura, shaman, with male first. The window starts on the player's own race if it is allowed.
|
||
- `<` / `>` step through the allowed races.
|
||
|
||
### Mob mode
|
||
- `SelectModel(vnum)`.
|
||
- Motion buttons: 待机 1, 攻击 13, 受击 5, 死亡 11, 技能1–4 33–36 (`InterceptOnceMotion`).
|
||
|
||
### Controls
|
||
- Dragging with the left button turns the camera: absolute yaw/pitch from the press point, pitch clamped to ±60°.
|
||
- 放大 / 缩小 change the zoom in 5 % steps, clamped to −8..+12. Windows have no wheel event.
|
||
- 自动旋转 spins the model.
|
||
- 复位 rebuilds the model, which also resets the camera.
|
||
|
||
### Lifetime
|
||
- Render target index 1 is created at 300×330 when the window opens.
|
||
- It is removed on close or Esc, and on every re-open before it is created again. `GameWindow.Close` also calls `renderTarget.Destroy()`.
|
||
- The host frees the GPU image 120 frames after its last use.
|
||
|
||
## Native side
|
||
|
||
- `renderTarget` Python module (`port/UserInterface/PythonRenderTargetModule.cpp`) → `CRenderTargetManager` → `CRenderTarget`, which owns a `CInstanceBase` and a `CGraphicRenderTargetTexture`.
|
||
- `CPythonApplication` calls `DeformModels` / `UpdateModels` / `RenderModels` around the character manager.
|
||
|
||
### Port differences from AVA2
|
||
- Player races (0..7) are created as `TYPE_PC`. 40250 reserves the armor/weapon/hair parts only for PCs, so AVA2's `TYPE_NPC` crashed on the first `ChangeArmor`.
|
||
- The model sits at the world origin, where culling hides it. Instead of AVA2's `SetAlwaysRender`, it is shown again before `Deform` and `Render`. Its text tail is detached.
|
||
- The background quad is drawn inside the render target, in `RenderModel`. `RenderBackgrounds` is a no-op.
|
||
- Wiki affects are not ported.
|
||
- The texture has 1 mip level.
|
||
|
||
### Host (Vulkan)
|
||
- A colour render target is `D3DFMT_X8R8G8B8` / `A8R8G8B8` with `D3DUSAGE_RENDERTARGET`, named `rt:<id>:<w>x<h>:c`.
|
||
- It gets its own RGBA8 offscreen pass (pipeline key bits 29–30: 0 none, 1 shadow, 2 colour) and is cleared to black.
|
||
- Shadow targets keep the previous path.
|
||
- Side effect: SnowEnvironment's blur targets now take the colour path. Snow blur is off by default.
|
||
|
||
## Verification
|
||
|
||
- `tests/wiki/test_model_preview.py` covers:
|
||
- `ItemSpec` races and slots;
|
||
- race stepping and fallback;
|
||
- motions and zoom clamps;
|
||
- drag;
|
||
- reset;
|
||
- the view drawing the target;
|
||
- no live target after close, Esc, or 5 re-opens;
|
||
- the inventory and shop wrappers;
|
||
- wiki links and module order.
|
||
- ctest 49/49.
|
||
- Live, channel5 13040, macOS client, 2026-10-16:
|
||
- armor 11299 on a warrior;
|
||
- sword 19 after a 90°/20° turn;
|
||
- wild dog 101 with the attack motion;
|
||
- boss 691 zoomed in with spin.
|
||
- The main scene was unchanged.
|
||
- 120 open/close cycles (30 paced, plus 60 in one frame) did not grow RSS: 668 MB before, 593 MB after.
|