EG/vr_quick_start.py
Rowland bb56813e44 feat(core): 优化 ALVR 串流功能并添加对 Pico 4 的支持
- 添加对有线连接的支持,特别是 Pico 4 的有线连接
- 改进 ALVR 服务器检测和连接逻辑
- 优化 VR 帧获取和处理流程
- 增加备用帧获取功能(主摄像机视图)
- 修复 VR 眼部纹理相关问题
- 优化 VR 任务管理,确保正确渲染和提交帧
2025-07-29 10:17:13 +08:00

263 lines
7.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
VR快速启动脚本
一键启动VR显示功能包括自动优化和ALVR串流
"""
import sys
import os
import time
from main import MyWorld
from vr_display_optimizer import VRDisplayOptimizer
def quick_vr_setup():
"""快速VR设置"""
print("🚀 VR快速启动")
print("=" * 40)
# 创建世界实例
print("🌍 初始化引擎...")
world = MyWorld()
# 创建优化器
optimizer = VRDisplayOptimizer(world)
# 设置基本场景
print("🎨 设置VR演示场景...")
setup_demo_scene(world)
# 初始化VR系统
print("🥽 启动VR系统...")
vr_success = world.initializeVR()
if not vr_success:
print("❌ VR初始化失败")
return None, None
print("✅ VR系统已启动")
# 优化VR性能
print("⚡ 优化VR性能...")
optimizer.optimize_vr_rendering()
# 尝试启动ALVR
print("📡 尝试启动ALVR串流...")
alvr_success = world.initializeALVR()
if alvr_success:
optimizer.optimize_alvr_streaming()
if world.startALVRStreaming():
print("✅ ALVR串流已启动")
else:
print("⚠️ ALVR串流启动失败")
else:
print("⚠️ ALVR初始化失败正常如果没有服务器")
# 启动VR输入
print("🎮 启动VR交互...")
if world.startVRInput():
world.showControllerRays(True)
world.setVRInteractionEnabled(True)
print("✅ VR交互已启用")
# 显示状态信息
print_vr_status(world)
return world, optimizer
def setup_demo_scene(world):
"""设置演示场景"""
try:
from panda3d.core import CardMaker, Vec4, AmbientLight, DirectionalLight
import math
# 添加光照
ambient = AmbientLight('ambient')
ambient.setColor(Vec4(0.4, 0.4, 0.4, 1))
ambient_np = world.render.attachNewNode(ambient)
world.render.setLight(ambient_np)
directional = DirectionalLight('sun')
directional.setColor(Vec4(1, 1, 0.9, 1))
directional.setDirection(Vec4(-1, -1, -1, 0))
sun_np = world.render.attachNewNode(directional)
world.render.setLight(sun_np)
# 创建地面
cm = CardMaker("ground")
cm.setFrame(-20, 20, -20, 20)
ground = world.render.attachNewNode(cm.generate())
ground.setPos(0, 0, -2)
ground.setHpr(0, -90, 0)
ground.setColor(0.3, 0.7, 0.3, 1)
# 创建彩色立方体环
for i in range(12):
cm_cube = CardMaker(f"cube_{i}")
cm_cube.setFrame(-0.5, 0.5, -0.5, 0.5)
cube = world.render.attachNewNode(cm_cube.generate())
angle = i * math.pi * 2 / 12
radius = 5
height = math.sin(i * 0.5) * 2
cube.setPos(math.cos(angle) * radius, math.sin(angle) * radius, height)
cube.setHpr(i * 30, 0, 0)
cube.setScale(1, 1, 2 + height * 0.5)
# HSV到RGB转换
h = i / 12.0 * 360
s = 0.8
v = 1.0
r, g, b = hsv_to_rgb(h, s, v)
cube.setColor(r, g, b, 1)
print(" ✅ 演示场景创建完成")
except Exception as e:
print(f" ⚠️ 场景创建失败: {str(e)}")
def hsv_to_rgb(h, s, v):
"""HSV到RGB颜色转换"""
import math
h = h / 60.0
c = v * s
x = c * (1 - abs((h % 2) - 1))
m = v - c
if 0 <= h < 1:
r, g, b = c, x, 0
elif 1 <= h < 2:
r, g, b = x, c, 0
elif 2 <= h < 3:
r, g, b = 0, c, x
elif 3 <= h < 4:
r, g, b = 0, x, c
elif 4 <= h < 5:
r, g, b = x, 0, c
else:
r, g, b = c, 0, x
return r + m, g + m, b + m
def print_vr_status(world):
"""显示VR状态信息"""
print("\n📊 VR系统状态")
print("-" * 30)
if world.isVREnabled():
vr_info = world.getVRInfo()
print(f"🥽 VR模式: {vr_info['mode']}")
print(f"📐 渲染尺寸: {vr_info['render_size']}")
print(f"🎮 模拟模式: {vr_info['simulation_mode']}")
if world.isALVRConnected():
status = world.getALVRStreamingStatus()
print(f"📡 ALVR状态: {'串流中' if world.isALVRStreaming() else '已连接'}")
print(f"🎥 分辨率: {status['resolution']}")
print(f"⚡ FPS: {status['fps']}")
else:
print("📡 ALVR状态: 未连接")
else:
print("🥽 VR状态: 未启用")
def run_vr_experience(world, optimizer, duration=30):
"""运行VR体验"""
print(f"\n🎮 VR体验开始 ({duration}秒)")
print("💡 控制说明:")
print(" - 观察窗口中的立体视图")
print(" - VR头盔中可看到完整场景")
print(" - 控制器射线用于交互")
print(" - 按Ctrl+C退出")
start_time = time.time()
frame_count = 0
try:
while time.time() - start_time < duration:
# 处理引擎更新
if hasattr(world, 'taskMgr'):
world.taskMgr.step()
frame_count += 1
# 每5秒显示状态
elapsed = time.time() - start_time
if frame_count % 300 == 0: # ~5秒
fps = frame_count / elapsed
print(f" 📈 运行状态: {elapsed:.1f}s, FPS: {fps:.1f}")
if world.isALVRStreaming():
alvr_status = world.getALVRStreamingStatus()
print(f" 📡 ALVR: {alvr_status['fps']} FPS, {alvr_status['latency']}ms延迟")
time.sleep(0.016) # ~60 FPS
except KeyboardInterrupt:
print("\n⏹️ 用户中断VR体验")
final_fps = frame_count / (time.time() - start_time)
print(f"✅ VR体验完成平均FPS: {final_fps:.1f}")
def cleanup_vr(world):
"""清理VR资源"""
print("\n🧹 清理VR资源...")
try:
if hasattr(world, 'stopVRInput'):
world.stopVRInput()
if hasattr(world, 'stopALVRStreaming'):
world.stopALVRStreaming()
if hasattr(world, 'shutdownALVR'):
world.shutdownALVR()
if hasattr(world, 'shutdownVR'):
world.shutdownVR()
print("✅ VR资源清理完成")
except Exception as e:
print(f"⚠️ VR清理失败: {str(e)}")
def main():
"""主函数"""
print("🎮 VR引擎快速启动")
print("=" * 50)
# 快速设置VR
world, optimizer = quick_vr_setup()
if not world:
print("❌ VR启动失败")
return
try:
# 运行VR体验
run_vr_experience(world, optimizer, 60) # 60秒演示
except Exception as e:
print(f"❌ VR运行错误: {str(e)}")
finally:
# 清理资源
cleanup_vr(world)
print("\n🎉 VR体验结束")
print("💡 要在Quest中体验:")
print(" 1. 安装ALVR服务器和客户端")
print(" 2. 连接同一WiFi网络")
print(" 3. 重新运行此脚本")
if __name__ == "__main__":
main()