package main import ( "encoding/json" "fmt" "html/template" "log" "net/http" ) 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

🎮 3D Visualization Control Panel

🍩 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}}
Current Scene: {{.CurrentScene}}

📋 System Logs

Connecting...
[Starting] WebUI Control panel loaded, connecting to log stream...
` // StartWebServer starts the web interface server func StartWebServer(params *TorusParams, cudaEnabled *bool) { // Serve static files for the web interface http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { tmpl := template.Must(template.New("index").Parse(htmlTemplate)) data := struct { TorusParams AsteroidParams CudaEnabled bool CurrentScene string }{ TorusParams: currentParams, AsteroidParams: currentAsteroidParams, CudaEnabled: cudaEnabled != nil && *cudaEnabled, CurrentScene: currentScene, } tmpl.Execute(w, data) }) // WebSocket endpoint for real-time logging http.HandleFunc("/ws", handleWebSocket) // 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 // Update the actual scene in main.go SetCurrentScene(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))) } } } // Update the actual asteroid config in main.go UpdateAsteroidConfig(currentAsteroidParams) 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 } // Call the actual clear function in main.go ClearAllAsteroids() 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 }