File size: 9,138 Bytes
cee5182 7aa89e4 cee5182 7aa89e4 cee5182 7aa89e4 cee5182 7aa89e4 cee5182 7aa89e4 cee5182 5b29015 cee5182 5b29015 cee5182 0614dda cee5182 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | """
Data models for GCP - Game Context Protocol
Using plain dictionaries for simplicity and clarity.
"""
from typing import Optional, Literal, Dict, Any, List
from datetime import datetime
import uuid
# Game Types
ObjectType = Literal["cube", "sphere", "cylinder", "plane", "cone", "torus", "model"]
LightType = Literal["ambient", "directional", "point", "spot", "hemisphere"]
LightingPreset = Literal["day", "night", "sunset", "studio"]
CameraMode = Literal["fps", "orbit", "top_down", "free"]
MaterialType = Literal["standard", "basic", "phong", "toon"]
# Factory functions for creating default data structures
def create_vector3(x: float = 0.0, y: float = 0.0, z: float = 0.0) -> Dict[str, float]:
"""Create a 3D vector for position, rotation, or scale."""
return {"x": x, "y": y, "z": z}
def create_material(
type: MaterialType = "standard",
color: str = "#ffffff",
metalness: float = 0.5,
roughness: float = 0.5,
opacity: float = 1.0,
wireframe: bool = False
) -> Dict[str, Any]:
"""Create material properties."""
return {
"type": type,
"color": color,
"metalness": metalness,
"roughness": roughness,
"opacity": opacity,
"wireframe": wireframe
}
def create_game_object(
object_type: ObjectType = "cube",
name: Optional[str] = None,
position: Optional[Dict[str, float]] = None,
rotation: Optional[Dict[str, float]] = None,
scale: Optional[Dict[str, float]] = None,
material: Optional[Dict[str, Any]] = None,
model_path: Optional[str] = None,
metadata: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
"""Create a 3D game object."""
return {
"id": str(uuid.uuid4()),
"name": name,
"type": object_type,
"position": position or create_vector3(),
"rotation": rotation or create_vector3(),
"scale": scale or create_vector3(1, 1, 1),
"material": material or create_material(),
"model_path": model_path,
"metadata": metadata or {},
"created_at": datetime.utcnow().isoformat()
}
def create_light(
light_type: LightType = "directional",
name: Optional[str] = None,
color: str = "#ffffff",
intensity: float = 1.0,
position: Optional[Dict[str, float]] = None,
target: Optional[Dict[str, float]] = None,
cast_shadow: bool = True,
ground_color: Optional[str] = None, # For hemisphere lights
distance: Optional[float] = None, # For point/spot lights
decay: float = 2.0 # Physically correct decay for point lights
) -> Dict[str, Any]:
"""
Create a light source.
Args:
light_type: Type of light (ambient, directional, point, spot, hemisphere)
name: Light name for identification
color: Light color in hex format (sky color for hemisphere)
intensity: Light intensity (0.0-2.0 typical, higher for specific effects)
position: Light position in 3D space
target: Target position for directional/spot lights
cast_shadow: Whether the light casts shadows (directional/spot only)
ground_color: Ground color for hemisphere lights (defaults to darker version of color)
distance: Maximum range for point/spot lights (0 = infinite)
decay: Light falloff rate for point/spot (2.0 = physically correct)
"""
light = {
"id": str(uuid.uuid4()),
"name": name,
"type": light_type,
"color": color,
"intensity": intensity,
"position": position or create_vector3(10, 10, 10),
"target": target,
"cast_shadow": cast_shadow,
}
# Add hemisphere-specific properties
if light_type == "hemisphere":
light["ground_color"] = ground_color or "#444444"
# Add point/spot-specific properties
if light_type in ["point", "spot"]:
if distance is not None:
light["distance"] = distance
light["decay"] = decay
return light
def create_environment(
background_color: str = "#87CEEB",
fog_enabled: bool = False,
fog_color: str = "#ffffff",
fog_near: float = 10.0,
fog_far: float = 100.0,
ambient_light_intensity: float = 0.5,
lighting_preset: LightingPreset = "day"
) -> Dict[str, Any]:
"""Create environment settings."""
return {
"background_color": background_color,
"fog_enabled": fog_enabled,
"fog_color": fog_color,
"fog_near": fog_near,
"fog_far": fog_far,
"ambient_light_intensity": ambient_light_intensity,
"lighting_preset": lighting_preset
}
def create_player(
position: Optional[Dict[str, float]] = None,
rotation: Optional[Dict[str, float]] = None,
camera_mode: CameraMode = "orbit",
movement_speed: float = 5.0,
look_sensitivity: float = 0.002
) -> Dict[str, Any]:
"""Create player/camera configuration."""
return {
"position": position or create_vector3(0, 5, 10),
"rotation": rotation or create_vector3(),
"camera_mode": camera_mode,
"movement_speed": movement_speed,
"look_sensitivity": look_sensitivity
}
def create_player_config(
move_speed: float = 8.0,
jump_force: float = 5.0,
mouse_sensitivity: float = 0.002,
invert_y: bool = False,
gravity: float = -9.82,
player_height: float = 1.7,
player_radius: float = 0.3,
eye_height: float = 1.6,
player_mass: float = 80.0,
linear_damping: float = 0.0,
movement_acceleration: float = 0.0,
air_control: float = 1.0,
camera_fov: float = 75.0,
min_pitch: float = -89.0,
max_pitch: float = 89.0
) -> Dict[str, Any]:
"""
Create player controller configuration for FPS mode.
Args:
move_speed: Horizontal movement speed in units/second
jump_force: Initial upward velocity for jumps in m/s
mouse_sensitivity: Mouse look sensitivity multiplier
invert_y: Whether to invert vertical mouse look
gravity: World gravity in m/s² (negative = downward)
player_height: Player collision capsule height in meters
player_radius: Player collision capsule radius in meters
eye_height: Camera height from player feet in meters
player_mass: Player body mass in kg
linear_damping: Air resistance (0.0-1.0, higher = more friction)
movement_acceleration: Acceleration time (0.0=instant, higher=slower)
air_control: Movement control while airborne (0.0-1.0)
camera_fov: Field of view in degrees (typical: 60-90)
min_pitch: Minimum vertical look angle in degrees (looking down)
max_pitch: Maximum vertical look angle in degrees (looking up)
Returns:
Dictionary with player controller configuration
"""
return {
"move_speed": move_speed,
"jump_force": jump_force,
"mouse_sensitivity": mouse_sensitivity,
"invert_y": invert_y,
"gravity": gravity,
"player_height": player_height,
"player_radius": player_radius,
"eye_height": eye_height,
"player_mass": player_mass,
"linear_damping": linear_damping,
"movement_acceleration": movement_acceleration,
"air_control": air_control,
"camera_fov": camera_fov,
"min_pitch": min_pitch,
"max_pitch": max_pitch
}
def create_scene(
name: str = "Untitled Scene",
description: Optional[str] = None,
world_width: float = 100.0,
world_height: float = 100.0,
world_depth: float = 100.0,
objects: Optional[List[Dict[str, Any]]] = None,
lights: Optional[List[Dict[str, Any]]] = None,
environment: Optional[Dict[str, Any]] = None,
player: Optional[Dict[str, Any]] = None,
show_grid: bool = False,
grid_size: float = 100.0,
grid_divisions: int = 20,
tags: Optional[List[str]] = None
) -> Dict[str, Any]:
"""Create a complete 3D scene."""
now = datetime.utcnow().isoformat()
return {
"scene_id": str(uuid.uuid4()),
"name": name,
"description": description,
"world_width": world_width,
"world_height": world_height,
"world_depth": world_depth,
"objects": objects or [],
"lights": lights or [],
"environment": environment or create_environment(),
"player": player or create_player(),
"show_grid": show_grid,
"grid_size": grid_size,
"grid_divisions": grid_divisions,
"tags": tags or [],
"created_at": now,
"updated_at": now
}
# Validation helpers (optional, for type checking)
def validate_vector3(v: Dict[str, float]) -> bool:
"""Check if a dict is a valid Vector3."""
return isinstance(v, dict) and all(k in v for k in ["x", "y", "z"])
def validate_lighting_preset(preset: str) -> bool:
"""Check if a string is a valid lighting preset."""
return preset in ["day", "night", "sunset", "studio"]
def validate_object_type(obj_type: str) -> bool:
"""Check if a string is a valid object type."""
return obj_type in ["cube", "sphere", "cylinder", "plane", "cone", "torus", "model"]
|