RobotMetaCore/src/impanda3d/scene.py
2026-04-24 15:19:09 +08:00

150 lines
5.2 KiB
Python

from __future__ import annotations
import math
from direct.showbase.ShowBase import ShowBase
from panda3d.core import (
AmbientLight,
DirectionalLight,
Material,
PointLight,
Vec3,
)
from .types import CameraState
def build_preview_scene(base: ShowBase):
base.render.set_shader_auto()
base.setBackgroundColor(0.16, 0.17, 0.19, 1.0)
base.disableMouse()
ambient = AmbientLight("ambient")
ambient.set_color((0.10, 0.10, 0.11, 1.0))
base.render.set_light(base.render.attachNewNode(ambient))
key_light = DirectionalLight("keyLight")
key_light.set_color((1.45, 1.40, 1.30, 1.0))
key_np = base.render.attachNewNode(key_light)
key_np.set_hpr(-38.0, -34.0, 0.0)
base.render.set_light(key_np)
fill_light = DirectionalLight("fillLight")
fill_light.set_color((0.38, 0.44, 0.52, 1.0))
fill_np = base.render.attachNewNode(fill_light)
fill_np.set_hpr(118.0, -18.0, 0.0)
base.render.set_light(fill_np)
rim_light = DirectionalLight("rimLight")
rim_light.set_color((0.30, 0.28, 0.26, 1.0))
rim_np = base.render.attachNewNode(rim_light)
rim_np.set_hpr(180.0, -8.0, 0.0)
base.render.set_light(rim_np)
bounce_light = PointLight("bounceLight")
bounce_light.set_color((0.22, 0.24, 0.28, 1.0))
bounce_np = base.render.attachNewNode(bounce_light)
bounce_np.set_pos(0.0, -1.5, 4.0)
base.render.set_light(bounce_np)
scene_root = base.render.attachNewNode("SceneRoot")
preview_root = scene_root.attachNewNode("PreviewRoot")
floor = base.loader.loadModel("models/box")
floor.set_name("Floor")
floor.reparentTo(scene_root)
floor.set_scale(9.5, 9.5, 0.08)
floor.set_pos(0.0, 0.0, -0.08)
floor_material = Material("FloorMaterial")
floor_material.set_base_color((0.43, 0.45, 0.48, 1.0))
floor_material.set_roughness(0.94)
floor_material.set_metallic(0.0)
floor.set_material(floor_material, 1)
backdrop = base.loader.loadModel("models/box")
backdrop.set_name("Backdrop")
backdrop.reparentTo(scene_root)
backdrop.set_scale(9.5, 0.12, 6.0)
backdrop.set_pos(0.0, 5.8, 3.8)
backdrop_material = Material("BackdropMaterial")
backdrop_material.set_base_color((0.24, 0.25, 0.28, 1.0))
backdrop_material.set_roughness(1.0)
backdrop_material.set_metallic(0.0)
backdrop.set_material(backdrop_material, 1)
pedestal_material = Material("PedestalMaterial")
pedestal_material.set_base_color((0.55, 0.57, 0.60, 1.0))
pedestal_material.set_roughness(0.82)
pedestal_material.set_metallic(0.0)
left_pedestal = base.loader.loadModel("models/box")
left_pedestal.set_name("LeftPedestal")
left_pedestal.reparentTo(scene_root)
left_pedestal.set_scale(1.15, 1.15, 0.55)
left_pedestal.set_pos(-3.4, 0.1, 0.55)
left_pedestal.set_material(pedestal_material, 1)
right_pedestal = base.loader.loadModel("models/box")
right_pedestal.set_name("RightPedestal")
right_pedestal.reparentTo(scene_root)
right_pedestal.set_scale(1.15, 1.15, 0.55)
right_pedestal.set_pos(3.4, 0.1, 0.55)
right_pedestal.set_material(pedestal_material, 1)
center_pedestal = base.loader.loadModel("models/box")
center_pedestal.set_name("CenterPedestal")
center_pedestal.reparentTo(scene_root)
center_pedestal.set_scale(1.55, 1.55, 0.34)
center_pedestal.set_pos(0.0, 0.1, 0.34)
center_pedestal.set_material(pedestal_material, 1)
smiley = base.loader.loadModel("models/smiley")
smiley.set_name("Smiley")
smiley.reparentTo(preview_root)
smiley.set_scale(1.55)
smiley.set_pos(-3.4, 0.1, 2.15)
smiley_material = Material("SmileyMaterial")
smiley_material.set_base_color((1.0, 0.95, 0.92, 1.0))
smiley_material.set_roughness(0.24)
smiley_material.set_metallic(0.02)
smiley.set_material(smiley_material, 1)
teapot = base.loader.loadModel("models/teapot")
teapot.set_name("Teapot")
teapot.reparentTo(preview_root)
teapot.set_scale(1.15)
teapot.set_hpr(25.0, 0.0, 0.0)
teapot.set_pos(0.0, 0.0, 1.12)
teapot_material = Material("TeapotMaterial")
teapot_material.set_base_color((0.80, 0.36, 0.24, 1.0))
teapot_material.set_roughness(0.42)
teapot_material.set_metallic(0.05)
teapot.set_material(teapot_material, 1)
cube = base.loader.loadModel("models/misc/rgbCube")
cube.set_name("PreviewCube")
cube.reparentTo(preview_root)
cube.set_scale(1.18)
cube.set_hpr(-28.0, 18.0, -12.0)
cube.set_pos(3.4, 0.1, 1.85)
cube_material = Material("PreviewCubeMaterial")
cube_material.set_base_color((0.72, 0.74, 0.78, 1.0))
cube_material.set_roughness(0.28)
cube_material.set_metallic(0.72)
cube.set_material(cube_material, 1)
return scene_root
def apply_camera_state(camera_np, camera: CameraState) -> None:
pitch_rad = math.radians(camera.pitch_deg)
heading_rad = math.radians(camera.heading_deg)
distance = max(camera.distance, 1.0)
x = camera.target_x + distance * math.cos(pitch_rad) * math.sin(heading_rad)
y = camera.target_y - distance * math.cos(pitch_rad) * math.cos(heading_rad)
z = camera.target_z + distance * math.sin(pitch_rad)
camera_np.set_pos(x, y, z)
camera_np.look_at(Vec3(camera.target_x, camera.target_y, camera.target_z))