167 lines
5.5 KiB
Python
167 lines
5.5 KiB
Python
|
|
# viewport3d_demo.py - Visual demo of Viewport3D integration
|
||
|
|
# Shows the 3D viewport as a UIDrawable alongside 2D elements
|
||
|
|
|
||
|
|
import mcrfpy
|
||
|
|
import sys
|
||
|
|
import math
|
||
|
|
|
||
|
|
# Create demo scene
|
||
|
|
scene = mcrfpy.Scene("viewport3d_demo")
|
||
|
|
|
||
|
|
# Dark background frame
|
||
|
|
bg = mcrfpy.Frame(pos=(0, 0), size=(1024, 768), fill_color=mcrfpy.Color(20, 20, 30))
|
||
|
|
scene.children.append(bg)
|
||
|
|
|
||
|
|
# Title
|
||
|
|
title = mcrfpy.Caption(text="Viewport3D Demo - PS1-Style 3D Rendering", pos=(20, 10))
|
||
|
|
title.fill_color = mcrfpy.Color(255, 255, 255)
|
||
|
|
scene.children.append(title)
|
||
|
|
|
||
|
|
# Create the 3D viewport - this is the star of the show!
|
||
|
|
viewport = mcrfpy.Viewport3D(
|
||
|
|
pos=(50, 60),
|
||
|
|
size=(600, 450),
|
||
|
|
render_resolution=(320, 240), # PS1 resolution for that retro look
|
||
|
|
fov=60.0,
|
||
|
|
camera_pos=(5.0, 3.0, 5.0),
|
||
|
|
camera_target=(0.0, 0.0, 0.0),
|
||
|
|
bg_color=mcrfpy.Color(25, 25, 50) # Dark blue background
|
||
|
|
)
|
||
|
|
scene.children.append(viewport)
|
||
|
|
|
||
|
|
# Info panel on the right
|
||
|
|
info_panel = mcrfpy.Frame(pos=(670, 60), size=(330, 450),
|
||
|
|
fill_color=mcrfpy.Color(30, 30, 40),
|
||
|
|
outline_color=mcrfpy.Color(80, 80, 100),
|
||
|
|
outline=2.0)
|
||
|
|
scene.children.append(info_panel)
|
||
|
|
|
||
|
|
# Panel title
|
||
|
|
panel_title = mcrfpy.Caption(text="Viewport Properties", pos=(690, 70))
|
||
|
|
panel_title.fill_color = mcrfpy.Color(200, 200, 255)
|
||
|
|
scene.children.append(panel_title)
|
||
|
|
|
||
|
|
# Property labels
|
||
|
|
props = [
|
||
|
|
("Position:", f"({viewport.x}, {viewport.y})"),
|
||
|
|
("Size:", f"{viewport.w}x{viewport.h}"),
|
||
|
|
("Render Res:", f"{viewport.render_resolution[0]}x{viewport.render_resolution[1]}"),
|
||
|
|
("FOV:", f"{viewport.fov} degrees"),
|
||
|
|
("Camera Pos:", f"({viewport.camera_pos[0]:.1f}, {viewport.camera_pos[1]:.1f}, {viewport.camera_pos[2]:.1f})"),
|
||
|
|
("Camera Target:", f"({viewport.camera_target[0]:.1f}, {viewport.camera_target[1]:.1f}, {viewport.camera_target[2]:.1f})"),
|
||
|
|
("", ""),
|
||
|
|
("PS1 Effects:", ""),
|
||
|
|
(" Vertex Snap:", "ON" if viewport.enable_vertex_snap else "OFF"),
|
||
|
|
(" Affine Map:", "ON" if viewport.enable_affine else "OFF"),
|
||
|
|
(" Dithering:", "ON" if viewport.enable_dither else "OFF"),
|
||
|
|
(" Fog:", "ON" if viewport.enable_fog else "OFF"),
|
||
|
|
(" Fog Range:", f"{viewport.fog_near} - {viewport.fog_far}"),
|
||
|
|
]
|
||
|
|
|
||
|
|
y_offset = 100
|
||
|
|
for label, value in props:
|
||
|
|
if label:
|
||
|
|
cap = mcrfpy.Caption(text=f"{label} {value}", pos=(690, y_offset))
|
||
|
|
cap.fill_color = mcrfpy.Color(180, 180, 200)
|
||
|
|
scene.children.append(cap)
|
||
|
|
y_offset += 22
|
||
|
|
|
||
|
|
# Instructions at bottom
|
||
|
|
instructions = mcrfpy.Caption(
|
||
|
|
text="[1-4] Toggle PS1 effects | [WASD] Move camera | [Q/E] Camera height | [ESC] Quit",
|
||
|
|
pos=(20, 530)
|
||
|
|
)
|
||
|
|
instructions.fill_color = mcrfpy.Color(150, 150, 150)
|
||
|
|
scene.children.append(instructions)
|
||
|
|
|
||
|
|
# Status line
|
||
|
|
status = mcrfpy.Caption(text="Status: Viewport3D rendering PS1-style 3D cube", pos=(20, 555))
|
||
|
|
status.fill_color = mcrfpy.Color(100, 200, 100)
|
||
|
|
scene.children.append(status)
|
||
|
|
|
||
|
|
# Animation state
|
||
|
|
animation_time = [0.0]
|
||
|
|
camera_orbit = [True]
|
||
|
|
|
||
|
|
# Camera orbit animation
|
||
|
|
def update_camera(timer, runtime):
|
||
|
|
animation_time[0] += runtime / 1000.0
|
||
|
|
|
||
|
|
if camera_orbit[0]:
|
||
|
|
# Orbit camera around origin
|
||
|
|
angle = animation_time[0] * 0.5 # Slow rotation
|
||
|
|
radius = 7.0
|
||
|
|
height = 4.0 + math.sin(animation_time[0] * 0.3) * 2.0
|
||
|
|
|
||
|
|
x = math.cos(angle) * radius
|
||
|
|
z = math.sin(angle) * radius
|
||
|
|
|
||
|
|
viewport.camera_pos = (x, height, z)
|
||
|
|
|
||
|
|
# Key handler
|
||
|
|
def on_key(key, state):
|
||
|
|
if state != mcrfpy.InputState.PRESSED:
|
||
|
|
return
|
||
|
|
|
||
|
|
key_name = str(key)
|
||
|
|
|
||
|
|
# Toggle PS1 effects with number keys
|
||
|
|
if key == mcrfpy.Key.NUM_1:
|
||
|
|
viewport.enable_vertex_snap = not viewport.enable_vertex_snap
|
||
|
|
status.text = f"Vertex Snap: {'ON' if viewport.enable_vertex_snap else 'OFF'}"
|
||
|
|
elif key == mcrfpy.Key.NUM_2:
|
||
|
|
viewport.enable_affine = not viewport.enable_affine
|
||
|
|
status.text = f"Affine Mapping: {'ON' if viewport.enable_affine else 'OFF'}"
|
||
|
|
elif key == mcrfpy.Key.NUM_3:
|
||
|
|
viewport.enable_dither = not viewport.enable_dither
|
||
|
|
status.text = f"Dithering: {'ON' if viewport.enable_dither else 'OFF'}"
|
||
|
|
elif key == mcrfpy.Key.NUM_4:
|
||
|
|
viewport.enable_fog = not viewport.enable_fog
|
||
|
|
status.text = f"Fog: {'ON' if viewport.enable_fog else 'OFF'}"
|
||
|
|
|
||
|
|
# Camera controls
|
||
|
|
elif key == mcrfpy.Key.SPACE:
|
||
|
|
camera_orbit[0] = not camera_orbit[0]
|
||
|
|
status.text = f"Camera orbit: {'ON' if camera_orbit[0] else 'OFF (manual control)'}"
|
||
|
|
|
||
|
|
elif key == mcrfpy.Key.ESCAPE:
|
||
|
|
mcrfpy.exit()
|
||
|
|
|
||
|
|
# Manual camera movement (when orbit is off)
|
||
|
|
if not camera_orbit[0]:
|
||
|
|
pos = list(viewport.camera_pos)
|
||
|
|
speed = 0.5
|
||
|
|
|
||
|
|
if key == mcrfpy.Key.W:
|
||
|
|
pos[2] -= speed
|
||
|
|
elif key == mcrfpy.Key.S:
|
||
|
|
pos[2] += speed
|
||
|
|
elif key == mcrfpy.Key.A:
|
||
|
|
pos[0] -= speed
|
||
|
|
elif key == mcrfpy.Key.D:
|
||
|
|
pos[0] += speed
|
||
|
|
elif key == mcrfpy.Key.Q:
|
||
|
|
pos[1] -= speed
|
||
|
|
elif key == mcrfpy.Key.E:
|
||
|
|
pos[1] += speed
|
||
|
|
|
||
|
|
viewport.camera_pos = tuple(pos)
|
||
|
|
status.text = f"Camera: ({pos[0]:.1f}, {pos[1]:.1f}, {pos[2]:.1f})"
|
||
|
|
|
||
|
|
# Set up scene
|
||
|
|
scene.on_key = on_key
|
||
|
|
|
||
|
|
# Create timer for camera animation
|
||
|
|
timer = mcrfpy.Timer("camera_update", update_camera, 16) # ~60fps
|
||
|
|
|
||
|
|
# Activate scene
|
||
|
|
mcrfpy.current_scene = scene
|
||
|
|
|
||
|
|
print("Viewport3D Demo loaded!")
|
||
|
|
print("3D rendering enabled - spinning colored cube should be visible.")
|
||
|
|
print()
|
||
|
|
print("Controls:")
|
||
|
|
print(" [1-4] Toggle PS1 effects")
|
||
|
|
print(" [Space] Toggle camera orbit")
|
||
|
|
print(" [WASD/QE] Manual camera control (when orbit off)")
|
||
|
|
print(" [ESC] Quit")
|