Skip to content

[WIP] Feature/morphtargets#2

Open
w0wca7a wants to merge 15 commits intow0wca7a:featuresfrom
madsiberian:feature/morphtargets
Open

[WIP] Feature/morphtargets#2
w0wca7a wants to merge 15 commits intow0wca7a:featuresfrom
madsiberian:feature/morphtargets

Conversation

@w0wca7a
Copy link
Copy Markdown
Owner

@w0wca7a w0wca7a commented Mar 24, 2026

PR Details

Related Issue

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My change requires a change to the documentation.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • I have built and run the editor to try this change out.

madsiberian and others added 15 commits March 17, 2026 12:24
Add full morph target support with up to 8 simultaneous targets:

- Position/normal/tangent morph shaders with weight array + active count
- MorphTargetRenderFeature: cbuffer upload with 16-byte aligned weights
- StrideEffectBase: MorphTargetMaxCount macro, conditional normal/tangent mixins
- MaterialKeys: HasMorphTargets, HasMorphTargetNormals/Tangents, MorphTargetMaxCount
- ModelComponent: SetMorphWeight/GetMorphWeight API (by name, index, or global)
- MeshConverter: glTF morph target import (positions, normals, tangents)
- ImportModelCommand: morph weight animation curve remapping
- GraphicsCompositorHelper: auto-inject MorphTargetRenderFeature
- MorphTargetSample: 2-target demo (X/Y shift, keys 1/2 to toggle)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 7 new tests for the multi-target morph target implementation:
- 8-target weight independence verification
- Multi-target rendering pipeline integration (2 targets)
- TransformationMorphTargetsKeys existence check
- MorphTargetMaxCount default value (8)
- Multi-target with normals and tangents rendering
- Max target count (8) simultaneous rendering stress test
- All 16 tests pass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove outdated TODO in MeshConverter.cs (remapping already implemented)
- Add GltfMorphTestScript for runtime glTF morph target testing (press G)
- Add Khronos AnimatedMorphCube.glb sample model for import testing
- Note: model must be imported via GameStudio to appear in asset bundle

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…editor UI

Fix morph target data loss during asset compilation:
- Prevent mesh merging from destroying morph target data (meshes with
  morph targets are now excluded from merge grouping)
- Copy MorphTargets field when creating merged or split meshes
- Scale morph position deltas when ScaleImport != 1.0
- Add ImportMorphTargets property to ModelAsset for opt-out control
- Strip morph targets early in ExportModel when import is disabled

Add "Import morph targets (blend shapes)" checkbox to GameStudio import
dialog with persistent settings, wired through the full pipeline from
ModelFromFileTemplateGenerator to ImportModelCommand.

Update MorphTargetSample with .sln file, imported AnimatedMorphCube
glTF asset, and adjusted GltfMorphTestScript spawn position/rotation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assimp morph anim channels use the node name (e.g. "AnimatedMorphCube")
as their key, but the mesh may have a different name (e.g. "Cube").
Add node-name-to-mesh-index fallback mapping so morph weight animation
curves are found even when the morph anim name doesn't match the mesh
name. Verified via build log that channels are correctly mapped:
  AnimatedMorphCube.MorphWeights[0] → [ModelComponent.Key].MeshInfos[0].MorphWeights[0]

Not yet verified at runtime due to NuGet packaging issues preventing
the sample from building end-to-end.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The animation system uses UpdateEngine to compile property paths like
[ModelComponent.Key].MeshInfos[0].MorphWeights[0] at runtime. This
was failing because:

1. MeshInfo lacked [DataContract] so the assembly processor never
   generated field bindings for MorphWeights
2. No ListUpdateResolver<MeshInfo> was registered, so MeshInfos[idx]
   indexing couldn't be resolved
3. MeshInfos was typed as IReadOnlyList<MeshInfo> which doesn't
   implement IList<T> needed by ListUpdateResolver

Fix: Add [DataContract] to MeshInfo, register ListUpdateResolver and
ArrayUpdateResolver in a [ModuleInitializer], and change MeshInfos
property type to List<MeshInfo>.

Add TestAnimationDrivenMorphWeights unit test that validates the full
animation playback path: AnimationClip → AnimationComponent → Play →
UpdateEngine → MeshInfos[0].MorphWeights[0] values change.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Press A to play a looping morph weight animation that oscillates both
targets using the same UpdateEngine path as imported animations:
[ModelComponent.Key].MeshInfos[0].MorphWeights[0]

Verified visually: morph targets animate continuously at runtime.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ation

Remove mannequin, UI, background, and render-to-texture entities from
the scene. Keep only lights, camera, and a MorphCube entity with
ModelComponent (AnimatedMorphCube) and GltfMorphTestScript.

Rewrite GltfMorphTestScript to use the entity it's attached to instead
of creating a new one programmatically. Auto-plays looping morph weight
animation on Start().

Verified end-to-end: glTF import → asset compilation with morph targets
→ runtime animation playback with visible morphing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Delete all mannequin-related files: model, skeleton, animations,
materials, textures, UI, render-to-texture, and associated scripts
(AnimationScript, UIScript, RotateEntity, RenderTextureSceneRenderer,
MorphTargetScript). Add AnimatedMorphCube animation asset and material
from glTF import. Update nuget.config to include merged NuGet source.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Load the compiled AnimatedMorphCube_Square.sdanim via Content.Load and
play it on the 'I' key, confirming the full asset pipeline end-to-end:
glTF import → asset compilation → .sdanim → AnimationComponent → GPU.

Also fix stale RenderTexture reference in GraphicsCompositor left over
from mannequin asset removal, which was blocking the asset compiler.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Display current animation mode (Programmatic/Imported/Manual) and
real-time morph weight values using DebugTextSystem. Shows key hints
for all controls.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract morph target names from source files at import time and display
them in the GameStudio property grid. The NodeUpdater shows a
"Morph Targets (N)" section with auto-expand when the source has morph
targets, and hides ImportMorphTargets when the source has none.

- EntityInfo: add MorphTargetNames field
- MeshConverter: extract names from Assimp AnimMeshes at import time
- ModelAsset: add read-only MorphTargetNames list property
- ModelAssetImporter: populate names from EntityInfo during import
- ModelAssetNodeUpdater: conditional display with count in header
- Remove unused Material_2.sdmat from sample

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…display it

The [Display(Browsable = false)] attribute prevented the property grid
from creating a node, causing the NodeUpdater to silently fail when
accessing it. Visibility is now controlled entirely by the NodeUpdater.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…to model asset

Remove the orphaned "Second camera" RenderTextureSceneRenderer from the
GraphicsCompositor (leftover from mannequin removal). Add MorphTargetNames
to AnimatedMorphCube.sdm3d so the property grid displays them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@w0wca7a w0wca7a changed the title Feature/morphtargets [WIP] Feature/morphtargets Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants