package main import ( "encoding/json" "fmt" "html/template" "log" "net/http" ) // TorusParams holds the configurable parameters for the torus type TorusParams struct { MajorRadius float32 `json:"majorRadius"` MinorRadius float32 `json:"minorRadius"` MajorSegments int `json:"majorSegments"` MinorSegments int `json:"minorSegments"` RotationSpeedX float32 `json:"rotationSpeedX"` RotationSpeedY float32 `json:"rotationSpeedY"` } // AsteroidParams holds configurable parameters for the asteroid field type AsteroidParams struct { SpawnRate float32 `json:"spawnRate"` MaxAsteroids int `json:"maxAsteroids"` MinSize float32 `json:"minSize"` MaxSize float32 `json:"maxSize"` MinSpeed float32 `json:"minSpeed"` MaxSpeed float32 `json:"maxSpeed"` RotationSpeed float32 `json:"rotationSpeed"` } var currentParams = TorusParams{ MajorRadius: 2.0, MinorRadius: 0.5, MajorSegments: 50, MinorSegments: 30, RotationSpeedX: 0.3, RotationSpeedY: 0.5, } var currentAsteroidParams = AsteroidParams{ SpawnRate: 1.0, MaxAsteroids: 500, MinSize: 0.05, MaxSize: 0.3, MinSpeed: 0.5, MaxSpeed: 3.0, RotationSpeed: 1.0, } var currentScene = "donut" // "donut" or "asteroids" const htmlTemplate = ` CUDA-Accelerated 3D Visualization Control Panel

🚀 CUDA-Accelerated 3D Visualization

Status: 3D Renderer Active

🍩 Torus Parameters

🌌 Asteroid Field Parameters

Info: This control panel adjusts the 3D visualization in real-time. Switch between the torus scene and asteroid field using the buttons above or press 1/2 in the 3D viewport.

Current Mode: {{if .CudaEnabled}}CUDA Accelerated{{else}}CPU Fallback{{end}}
Keyboard Shortcuts: 1 = Torus Scene, 2 = Asteroid Field, ESC = Exit

📊 Application Logs

00:00:00 [System] Connecting to log stream...
` // StartWebServer starts the web interface server func StartWebServer(params *TorusParams, cudaEnabled *bool) { // Update global reference if params != nil { currentParams = *params } tmpl, err := template.New("index").Parse(htmlTemplate) if err != nil { log.Printf("Template parsing error: %v", err) return } // WebSocket endpoint for logs http.HandleFunc("/ws/logs", wsLogHandler) // Serve the main page http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { data := struct { TorusParams AsteroidParams CudaEnabled bool }{ TorusParams: currentParams, AsteroidParams: currentAsteroidParams, CudaEnabled: cudaEnabled != nil && *cudaEnabled, } tmpl.Execute(w, data) }) // API endpoint for scene switching http.HandleFunc("/api/scene", func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } var sceneData map[string]string if err := json.NewDecoder(r.Body).Decode(&sceneData); err != nil { http.Error(w, "Invalid JSON", http.StatusBadRequest) return } if scene, ok := sceneData["scene"]; ok { currentScene = scene LogSuccess("Scene", fmt.Sprintf("Scene switched to: %s", scene)) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"status": "scene changed"}) }) // API endpoint to update torus parameters http.HandleFunc("/api/params", func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } var updates map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&updates); err != nil { http.Error(w, "Invalid JSON", http.StatusBadRequest) return } // Log parameter changes for key, value := range updates { LogInfo("UI", fmt.Sprintf("Torus parameter changed: %s = %v", key, value)) } // Update parameters for key, value := range updates { switch key { case "majorRadius": if v, ok := value.(float64); ok { oldValue := currentParams.MajorRadius currentParams.MajorRadius = float32(v) LogSuccess("Parameters", fmt.Sprintf("Major Radius: %.2f → %.2f", oldValue, float32(v))) } case "minorRadius": if v, ok := value.(float64); ok { oldValue := currentParams.MinorRadius currentParams.MinorRadius = float32(v) LogSuccess("Parameters", fmt.Sprintf("Minor Radius: %.3f → %.3f", oldValue, float32(v))) } case "majorSegments": if v, ok := value.(float64); ok { oldValue := currentParams.MajorSegments currentParams.MajorSegments = int(v) LogSuccess("Parameters", fmt.Sprintf("Major Segments: %d → %d", oldValue, int(v))) } case "minorSegments": if v, ok := value.(float64); ok { oldValue := currentParams.MinorSegments currentParams.MinorSegments = int(v) LogSuccess("Parameters", fmt.Sprintf("Minor Segments: %d → %d", oldValue, int(v))) } case "rotationSpeedX": if v, ok := value.(float64); ok { oldValue := currentParams.RotationSpeedX currentParams.RotationSpeedX = float32(v) LogSuccess("Parameters", fmt.Sprintf("X Rotation Speed: %.1f → %.1f", oldValue, float32(v))) } case "rotationSpeedY": if v, ok := value.(float64); ok { oldValue := currentParams.RotationSpeedY currentParams.RotationSpeedY = float32(v) LogSuccess("Parameters", fmt.Sprintf("Y Rotation Speed: %.1f → %.1f", oldValue, float32(v))) } } } // Copy back to the main params if provided if params != nil { *params = currentParams } LogInfo("System", "Torus parameters updated successfully") w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"status": "updated"}) }) // API endpoint to update asteroid parameters http.HandleFunc("/api/asteroid-params", func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } var updates map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&updates); err != nil { http.Error(w, "Invalid JSON", http.StatusBadRequest) return } // Log parameter changes for key, value := range updates { LogInfo("UI", fmt.Sprintf("Asteroid parameter changed: %s = %v", key, value)) } // Update parameters for key, value := range updates { switch key { case "spawnRate": if v, ok := value.(float64); ok { oldValue := currentAsteroidParams.SpawnRate currentAsteroidParams.SpawnRate = float32(v) LogSuccess("Asteroids", fmt.Sprintf("Spawn Rate: %.1f → %.1f", oldValue, float32(v))) } case "maxAsteroids": if v, ok := value.(float64); ok { oldValue := currentAsteroidParams.MaxAsteroids currentAsteroidParams.MaxAsteroids = int(v) LogSuccess("Asteroids", fmt.Sprintf("Max Asteroids: %d → %d", oldValue, int(v))) } case "minSize": if v, ok := value.(float64); ok { oldValue := currentAsteroidParams.MinSize currentAsteroidParams.MinSize = float32(v) LogSuccess("Asteroids", fmt.Sprintf("Min Size: %.3f → %.3f", oldValue, float32(v))) } case "maxSize": if v, ok := value.(float64); ok { oldValue := currentAsteroidParams.MaxSize currentAsteroidParams.MaxSize = float32(v) LogSuccess("Asteroids", fmt.Sprintf("Max Size: %.3f → %.3f", oldValue, float32(v))) } case "minSpeed": if v, ok := value.(float64); ok { oldValue := currentAsteroidParams.MinSpeed currentAsteroidParams.MinSpeed = float32(v) LogSuccess("Asteroids", fmt.Sprintf("Min Speed: %.1f → %.1f", oldValue, float32(v))) } case "maxSpeed": if v, ok := value.(float64); ok { oldValue := currentAsteroidParams.MaxSpeed currentAsteroidParams.MaxSpeed = float32(v) LogSuccess("Asteroids", fmt.Sprintf("Max Speed: %.1f → %.1f", oldValue, float32(v))) } case "rotationSpeed": if v, ok := value.(float64); ok { oldValue := currentAsteroidParams.RotationSpeed currentAsteroidParams.RotationSpeed = float32(v) LogSuccess("Asteroids", fmt.Sprintf("Rotation Speed: %.1f → %.1f", oldValue, float32(v))) } } } LogInfo("System", "Asteroid parameters updated successfully") w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"status": "updated"}) }) // API endpoint to clear asteroids http.HandleFunc("/api/clear-asteroids", func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } LogInfo("Asteroids", "Clearing all asteroids from field") w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"status": "asteroids cleared"}) }) // API endpoint for status http.HandleFunc("/api/status", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "cudaEnabled": cudaEnabled != nil && *cudaEnabled, "params": currentParams, "asteroidParams": currentAsteroidParams, "currentScene": currentScene, }) }) LogInfo("WebServer", "Starting web interface on http://localhost:8080") LogInfo("WebServer", "Access the control panel and logs in your browser") log.Fatal(http.ListenAndServe(":8080", nil)) } // GetCurrentParams returns the current torus parameters func GetCurrentParams() TorusParams { return currentParams } // GetCurrentAsteroidParams returns the current asteroid parameters func GetCurrentAsteroidParams() AsteroidParams { return currentAsteroidParams } // GetCurrentScene returns the current scene name func GetCurrentScene() string { return currentScene }