Skip to content
This repository was archived by the owner on Mar 19, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
00014d9
VR ロコモーションコンポーネントを追加
HMasataka Mar 7, 2026
9c90a07
StereoCamera に HmdRotation フィールドを追加
HMasataka Mar 7, 2026
2cfc915
VR スムース移動とアームスイングを実装
HMasataka Mar 7, 2026
e37d67c
VR テレポートを実装
HMasataka Mar 7, 2026
7be9201
roadmap.md v0.13 を完了に更新
HMasataka Mar 7, 2026
f5b3705
Forward+ シェーダーの埋め込みリソース名を実ファイル名に修正
HMasataka Mar 8, 2026
1b5884c
Forward+ コンポジットパスを修正し VR オパック描画結果を表示
HMasataka Mar 8, 2026
d1f2e11
VR グラブの即リリースと飛び挙動を修正
HMasataka Mar 8, 2026
bbd9825
Forward+ opaque シェーダーにディレクショナルライトを追加
HMasataka Mar 8, 2026
2c89d9f
VR ロコモーション有効化とデスクトップミラー描画を追加
HMasataka Mar 8, 2026
4e81e41
Forward+ シェーダーにモデル行列と視点位置を追加し PBR ライティングを修正
HMasataka Mar 8, 2026
f150d3e
XrInputUpdateSystem で HMD ポーズを StereoCamera に書き込み VR ロコモーションを修正
HMasataka Mar 8, 2026
f535d1c
GrabState に GrabbedByHand を追加し VR グラブの即リリースを修正
HMasataka Mar 8, 2026
01450a8
VR ディスタンスグラブのプル中断とターゲット喪失を修正
HMasataka Mar 8, 2026
37cbfe8
XrInputDevice で MoveAxis/LookDelta へのスティック入力を除外
HMasataka Mar 8, 2026
2c9d9f3
StereoCamera にプレイヤー位置を追加し VR ロコモーションとオペーク描画を修正
HMasataka Mar 8, 2026
4baca1f
Forward+ ディスクリプタセットに正しいバインディングを設定し VR の黒画面を修正
HMasataka Mar 8, 2026
e8859ac
StereoCamera に PlayerRotation を追加しスナップターンの基盤を整備
HMasataka Mar 8, 2026
01f0e1d
右スティックによるスナップターンシステムを追加
HMasataka Mar 8, 2026
91aff53
スナップターン回転をレンダリングと移動方向に反映
HMasataka Mar 8, 2026
6edb847
右手系に合わせてスナップターンの回転方向を修正
HMasataka Mar 8, 2026
0922970
VR グラブにプレイヤー移動・回転の追従を追加
HMasataka Mar 8, 2026
4e43a21
GrabOffset をステージ空間で保存しスナップターン時の追従を修正
HMasataka Mar 8, 2026
07b8294
グラブ中オブジェクトの向きもスナップターンに追従させる
HMasataka Mar 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@

ゴール: VR特有の移動方式を揃える

- [ ] テレポート (アーク表示、ナビメッシュ判定、フェード遷移、方向選択)
- [ ] スムース移動 (左スティック、ビネットエフェクト)
- [ ] アームスイング (コントローラー振り動作、最大5.0m/s)
- [x] テレポート (アーク表示、ナビメッシュ判定、フェード遷移、方向選択)
- [x] スムース移動 (左スティック、ビネットエフェクト)
- [x] アームスイング (コントローラー振り動作、最大5.0m/s)

完動品としての価値: VRで3方式の移動が選べる。酔い対策も入っている。

Expand Down
304 changes: 269 additions & 35 deletions src/Seed.Engine.App/Program.cs

Large diffs are not rendered by default.

162 changes: 162 additions & 0 deletions src/Seed.Engine.Tests/Ecs/Components/VrLocomotionComponentTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
using System;
using System.Runtime.InteropServices;
using Xunit;

using Seed.Engine.Ecs;
using Seed.Engine.Ecs.Components;
using Seed.Engine.Foundation.Mathematics;

namespace Seed.Engine.Tests.Ecs.Components;

public class VrLocomotionComponentTests
{
[Fact]
public void VrLocomotionMode_ImplementsIComponent()
{
// Given
VrLocomotionMode mode = new VrLocomotionMode
{
ActiveMode = LocomotionType.SmoothMove,
DirectionSource = 1,
VignetteEnabled = 1,
};

// Then
Assert.Equal(LocomotionType.SmoothMove, mode.ActiveMode);
Assert.Equal((byte)1, mode.DirectionSource);
Assert.Equal((byte)1, mode.VignetteEnabled);
}

[Fact]
public void VrLocomotionMode_RegistersAsComponent()
{
// When
var compType = ComponentRegistry.Get<VrLocomotionMode>();

// Then
Assert.True(compType.TypeId > 0);
Assert.True(compType.Size > 0);
}

[Fact]
public void VrLocomotionConfig_ImplementsIComponent()
{
// Given
VrLocomotionConfig config = new VrLocomotionConfig
{
TeleportMaxDistance = 10.0f,
TeleportFadeDuration = 0.15f,
SmoothMoveSpeed = 2.0f,
ArmSwingMaxSpeed = 5.0f,
ArmSwingMultiplier = 2.0f,
};

// Then
Assert.Equal(10.0f, config.TeleportMaxDistance);
Assert.Equal(0.15f, config.TeleportFadeDuration);
Assert.Equal(2.0f, config.SmoothMoveSpeed);
Assert.Equal(5.0f, config.ArmSwingMaxSpeed);
}

[Fact]
public void VrLocomotionConfig_RegistersAsComponent()
{
// When
var compType = ComponentRegistry.Get<VrLocomotionConfig>();

// Then
Assert.True(compType.TypeId > 0);
Assert.True(compType.Size > 0);
}

[Fact]
public void TeleportState_ImplementsIComponent()
{
// Given
TeleportState state = new TeleportState
{
Phase = TeleportPhase.Aiming,
IsTargetValid = 1,
TargetPosition = new Vector3(1f, 0f, -3f),
TargetYaw = 1.57f,
FadeElapsed = 0.1f,
};

// Then
Assert.Equal(TeleportPhase.Aiming, state.Phase);
Assert.Equal((byte)1, state.IsTargetValid);
Assert.Equal(1.57f, state.TargetYaw);
}

[Fact]
public void TeleportState_RegistersAsComponent()
{
// When
var compType = ComponentRegistry.Get<TeleportState>();

// Then
Assert.True(compType.TypeId > 0);
Assert.True(compType.Size > 0);
}

[Fact]
public void VignetteState_ImplementsIComponent()
{
// Given
VignetteState vignette = new VignetteState
{
Intensity = 0.8f,
};

// Then
Assert.Equal(0.8f, vignette.Intensity);
}

[Fact]
public void VignetteState_RegistersAsComponent()
{
// When
var compType = ComponentRegistry.Get<VignetteState>();

// Then
Assert.True(compType.TypeId > 0);
Assert.True(compType.Size > 0);
}

[Fact]
public void LocomotionType_EnumValues()
{
Assert.Equal((byte)0, (byte)LocomotionType.Teleport);
Assert.Equal((byte)1, (byte)LocomotionType.SmoothMove);
Assert.Equal((byte)2, (byte)LocomotionType.ArmSwing);
}

[Fact]
public void TeleportPhase_EnumValues()
{
Assert.Equal((byte)0, (byte)TeleportPhase.Idle);
Assert.Equal((byte)1, (byte)TeleportPhase.Aiming);
Assert.Equal((byte)2, (byte)TeleportPhase.FadingOut);
Assert.Equal((byte)3, (byte)TeleportPhase.FadingIn);
}

[Fact]
public void VrLocomotionMode_IsMarshalable()
{
// Given/When: Marshal.SizeOf succeeds only for sequential/explicit layout
int size = Marshal.SizeOf<VrLocomotionMode>();

// Then
Assert.True(size > 0);
}

[Fact]
public void TeleportState_IsMarshalable()
{
// Given/When
int size = Marshal.SizeOf<TeleportState>();

// Then
Assert.True(size > 0);
}
}
Loading