Skip to content
Draft
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions fission/src/Synthesis.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AnimatePresence } from "framer-motion"
import React, { ReactElement, useCallback, useEffect, useRef, useState } from "react"
import type React from "react"
import { type ReactElement, useCallback, useEffect, useRef, useState } from "react"
import MainHUD from "@/components/MainHUD"
import Scene from "@/components/Scene.tsx"
import ConnectToMultiplayerModal from "@/modals/aether/ConnectToMultiplayerModal"
Expand Down Expand Up @@ -42,9 +43,9 @@ import ImportMirabufPanel from "@/ui/panels/mirabuf/ImportMirabufPanel.tsx"
import { ToastContainer, ToastProvider } from "@/ui/ToastContext"
import {
TOOLTIP_DURATION,
TooltipControl,
type TooltipControl,
TooltipControlProvider,
TooltipType,
type TooltipType,
useTooltipManager,
} from "@/ui/TooltipContext"
import PreferencesSystem from "./systems/preferences/PreferencesSystem.ts"
Expand All @@ -57,6 +58,7 @@ import SceneOverlay from "./ui/components/SceneOverlay.tsx"
import Skybox from "./ui/components/Skybox.tsx"
import TouchControls from "./ui/components/TouchControls.tsx"
import WPILibConnectionStatus from "./ui/components/WPILibConnectionStatus.tsx"
import { applyInitialGraphicsSettings } from "./ui/helpers/GraphicsSettings.ts"
import APSManagementModal from "./ui/modals/APSManagementModal.tsx"
import AssignNewSchemeModal from "./ui/modals/configuring/theme-editor/AssignNewSchemeModal.tsx"
import NewInputSchemeModal from "./ui/modals/configuring/theme-editor/NewInputSchemeModal.tsx"
Expand Down Expand Up @@ -99,6 +101,8 @@ const Synthesis: React.FC = () => {
startSingleplayerCallback={() => {
World.initWorld()

applyInitialGraphicsSettings()

if (!PreferencesSystem.getGlobalPreference("ReportAnalytics") && !import.meta.env.DEV) {
setConsentPopupDisable(false)
}
Expand Down
2 changes: 2 additions & 0 deletions fission/src/systems/preferences/PreferenceTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type GlobalPreferences = {
MuteAllSound: boolean
SFXVolume: number
ShowCenterOfMassIndicators: boolean
GraphicsOptimizationApplied: boolean
}

export type GlobalPreference = keyof GlobalPreferences
Expand Down Expand Up @@ -66,6 +67,7 @@ export const defaultGlobalPreferences: GlobalPreferences = {
MuteAllSound: false,
SFXVolume: 25,
ShowCenterOfMassIndicators: false,
GraphicsOptimizationApplied: false,
}

export type GraphicsPreferences = {
Expand Down
110 changes: 110 additions & 0 deletions fission/src/ui/helpers/GraphicsSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import PreferencesSystem from "@/systems/preferences/PreferencesSystem"
import { globalAddToast } from "@/ui/components/GlobalUIControls"

export type GraphicsPreset = "Fast" | "Balanced" | "Fancy"

export const GRAPHICS_PRESETS: Record<
GraphicsPreset,
{
lightIntensity: number
fancyShadows: boolean
maxFar: number
cascades: number
shadowMapSize: number
antiAliasing: boolean
}
> = {
Fast: {
lightIntensity: 3.5,
fancyShadows: false,
maxFar: 20,
cascades: 3,
shadowMapSize: 1024,
antiAliasing: false,
},
Balanced: {
lightIntensity: 5,
fancyShadows: true,
maxFar: 30,
cascades: 4,
shadowMapSize: 2048,
antiAliasing: false,
},
Fancy: {
lightIntensity: 8,
fancyShadows: true,
maxFar: 40,
cascades: 6,
shadowMapSize: 8192,
antiAliasing: true,
},
}

export const isMobileDevice = (): boolean => {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
}

export const isLowEndDevice = (): boolean => {
if (isMobileDevice()) return true

const memory =
typeof navigator !== "undefined" && "deviceMemory" in navigator
? (navigator as Navigator & { deviceMemory?: number }).deviceMemory
: undefined
if (memory !== undefined && memory <= 4) return true // 4GB or less RAM
Comment thread
AlexD717 marked this conversation as resolved.

const cores = navigator.hardwareConcurrency
if (cores && cores <= 2) return true // 2 cores or less

const userAgent = navigator.userAgent.toLowerCase()
if (userAgent.includes("android") && (userAgent.includes("lite") || userAgent.includes("go"))) return true

return false
}

export const autoOptimizeGraphics = (toastType: "long" | "short" | "none" = "none"): GraphicsPreset => {
if (isLowEndDevice()) {
if (toastType === "long") {
globalAddToast?.(
"info",
"Graphics Optimized",
"We've set your graphics to 'Fast' mode for optimal performance on your device. You can change this in Graphics Settings."
)
} else if (toastType === "short") {
globalAddToast?.("info", "Success", "Auto-optimized graphics to 'Fast'.")
}
return "Fast"
} else {
if (toastType === "long") {
globalAddToast?.(
"info",
"Graphics Optimized",
"We've set your graphics to 'Balanced' mode for optimal performance on your device. You can change this in Graphics Settings."
)
} else if (toastType === "short") {
globalAddToast?.("info", "Success", "Auto-optimized graphics to 'Balanced'.")
}
return "Balanced"
}
}

export const applyInitialGraphicsSettings = (): void => {
// Check if graphics optimization has already been applied
const optimizationApplied = PreferencesSystem.getGlobalPreference("GraphicsOptimizationApplied")

// If optimization hasn't been applied yet and device should use fast mode, apply fast settings
if (!optimizationApplied) {
const presetToApply = autoOptimizeGraphics("long")
const settings = GRAPHICS_PRESETS[presetToApply]
PreferencesSystem.getGraphicsPreferences().lightIntensity = settings.lightIntensity
PreferencesSystem.getGraphicsPreferences().fancyShadows = settings.fancyShadows
PreferencesSystem.getGraphicsPreferences().maxFar = settings.maxFar
PreferencesSystem.getGraphicsPreferences().cascades = settings.cascades
PreferencesSystem.getGraphicsPreferences().shadowMapSize = settings.shadowMapSize
PreferencesSystem.getGraphicsPreferences().antiAliasing = settings.antiAliasing

// Mark that optimization has been applied
PreferencesSystem.setGlobalPreference("GraphicsOptimizationApplied", true)
PreferencesSystem.savePreferences()
}
}
7 changes: 5 additions & 2 deletions fission/src/ui/modals/configuring/SettingsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import { useModalControlContext } from "@/ui/helpers/UseModalManager"
import { usePanelControlContext } from "@/ui/helpers/UsePanelManager"

const StatefulSlider: React.FC<
Omit<Parameters<typeof Slider>[0], "value" | "onChange"> & { defaultValue: number; onChange: (val: number) => void }
Omit<Parameters<typeof Slider>[0], "value" | "onChange"> & {
defaultValue: number
onChange: (val: number) => void
}
> = props => {
const [value, setValue] = useState(props.defaultValue)
return (
Expand Down Expand Up @@ -54,7 +57,7 @@ const SettingsModal: React.FC<ModalPropsImpl> = ({ modalId }) => {
onClick={() => {
openPanel("graphics-settings")
closeModal()
save()
// save()
}}
/>
</Box>
Expand Down
Loading
Loading