diff --git a/src/api/nitro/room/DispatchResizeEvent.ts b/src/api/nitro/room/DispatchResizeEvent.ts deleted file mode 100644 index 04391187..00000000 --- a/src/api/nitro/room/DispatchResizeEvent.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Nitro } from 'nitro-renderer'; -import { InitializeRoomInstanceRenderingCanvas } from './InitializeRoomInstanceRenderingCanvas'; - -let resizeTimer: ReturnType = null; - -export function WindowResizeEvent(roomId: number, canvasId: number) -{ - if(resizeTimer) clearTimeout(resizeTimer); - - resizeTimer = setTimeout(() => - { - Nitro.instance.renderer.resize(window.innerWidth, window.innerHeight); - - InitializeRoomInstanceRenderingCanvas(roomId, canvasId, Nitro.instance.width, Nitro.instance.height); - - //this._events.dispatchEvent(new RoomWidgetRoomViewUpdateEvent(RoomWidgetRoomViewUpdateEvent.SIZE_CHANGED, this.getRoomViewRect())); - - //this.setRoomBackground(); - - Nitro.instance.render(); - }, 1); -} diff --git a/src/api/nitro/room/index.ts b/src/api/nitro/room/index.ts index 6a06237f..b18567a6 100644 --- a/src/api/nitro/room/index.ts +++ b/src/api/nitro/room/index.ts @@ -1,5 +1,4 @@ export * from './DispatchMouseEvent'; -export * from './DispatchResizeEvent'; export * from './DispatchTouchEvent'; export * from './GetOwnRoomObject'; export * from './GetRoomEngine'; diff --git a/src/views/room/RoomColorView.tsx b/src/views/room/RoomColorView.tsx new file mode 100644 index 00000000..b298becf --- /dev/null +++ b/src/views/room/RoomColorView.tsx @@ -0,0 +1,152 @@ +import { ColorConverter, Nitro, NitroAdjustmentFilter, NitroContainer, NitroSprite, NitroTexture, RoomBackgroundColorEvent, RoomEngineEvent, RoomId, RoomObjectHSLColorEnabledEvent } from 'nitro-renderer'; +import { FC, useCallback, useState } from 'react'; +import { GetRoomEngine } from '../../api'; +import { UseMountEffect } from '../../hooks'; +import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../hooks/events'; +import { useRoomContext } from './context/RoomContext'; +import { RoomWidgetUpdateRoomViewEvent } from './events/RoomWidgetUpdateRoomViewEvent'; + +const ROOM_FILTER: NitroAdjustmentFilter = new NitroAdjustmentFilter(); + +export const RoomColorView: FC<{}> = props => +{ + const [ roomBackground, setRoomBackground ] = useState(null); + const [ roomBackgroundColor, setRoomBackgroundColor ] = useState(0x000000); + const [ roomFilter, setRoomFilter ] = useState(null); + const [ roomFilterColor, setRoomFilterColor ] = useState(-1); + const { roomSession = null, canvasId = -1, eventDispatcher = null } = useRoomContext(); + + const getRenderingCanvas = useCallback(() => + { + return GetRoomEngine().getRoomInstanceRenderingCanvas(roomSession.roomId, canvasId); + }, [ roomSession, canvasId ]); + + const getRoomBackground = useCallback(() => + { + if(roomBackground) return roomBackground; + + const canvas = getRenderingCanvas(); + + if(!canvas) return null; + + const displayObject = (canvas.master as NitroContainer); + const background = new NitroSprite(NitroTexture.WHITE); + + displayObject.addChildAt(background, 0); + + setRoomBackground(background); + + return background; + }, [ roomBackground, getRenderingCanvas ]); + + const updateRoomBackground = useCallback(() => + { + const background = getRoomBackground(); + + if(!background) return; + + background.tint = roomBackgroundColor; + background.width = Nitro.instance.width; + background.height = Nitro.instance.height; + }, [ roomBackgroundColor, getRoomBackground ]); + + const updateRoomBackgroundColor = useCallback((hue: number, saturation: number, lightness: number) => + { + setRoomBackgroundColor(ColorConverter.hslToRGB(((((hue & 0xFF) << 16) + ((saturation & 0xFF) << 8)) + (lightness & 0xFF)))); + + const background = getRoomBackground(); + + if(!background) return; + + if(!hue && !saturation && !lightness) + { + background.visible = false; + } + else + { + updateRoomBackground(); + + background.visible = true; + } + }, [ getRoomBackground, updateRoomBackground ]); + + const getRoomFilter = useCallback(() => + { + if(roomFilter) return roomFilter; + + const canvas = getRenderingCanvas(); + + if(!canvas) return null; + + const display = canvas.master; + + if(!display) return null; + + setRoomFilter(ROOM_FILTER); + + display.filters = [ ROOM_FILTER ]; + + return ROOM_FILTER; + }, [ roomFilter, getRenderingCanvas ]); + + const updateRoomFilter = useCallback(() => + { + const colorMatrix = getRoomFilter(); + + if(!colorMatrix) return; + + const r = ((roomFilterColor >> 16) & 0xFF); + const g = ((roomFilterColor >> 8) & 0xFF); + const b = (roomFilterColor & 0xFF); + + colorMatrix.red = (r / 255); + colorMatrix.green = (g / 255); + colorMatrix.blue = (b / 255); + }, [ roomFilterColor, getRoomFilter ]); + + const updateRoomFilterColor = useCallback((color: number, brightness: number) => + { + setRoomFilterColor(ColorConverter.hslToRGB(((ColorConverter.rgbToHSL(color) & 0xFFFF00) + brightness))); + + updateRoomFilter(); + }, [ updateRoomFilter ]); + + const onRoomEngineEvent = useCallback((event: RoomEngineEvent) => + { + if(!RoomId.isRoomPreviewerId(event.roomId)) return; + + switch(event.type) + { + case RoomObjectHSLColorEnabledEvent.ROOM_BACKGROUND_COLOR: { + const hslColorEvent = (event as RoomObjectHSLColorEnabledEvent); + + if(hslColorEvent.enable) updateRoomBackgroundColor(hslColorEvent.hue, hslColorEvent.saturation, hslColorEvent.lightness); + else updateRoomBackgroundColor(0, 0, 0); + + return; + } + case RoomBackgroundColorEvent.ROOM_COLOR: { + const colorEvent = (event as RoomBackgroundColorEvent); + + if(colorEvent.bgOnly) updateRoomFilterColor(0xFF0000, 0xFF); + else updateRoomFilterColor(colorEvent.color, colorEvent.brightness); + + return; + } + } + }, [ updateRoomBackgroundColor, updateRoomFilterColor ]); + + useRoomEngineEvent(RoomObjectHSLColorEnabledEvent.ROOM_BACKGROUND_COLOR, onRoomEngineEvent); + useRoomEngineEvent(RoomBackgroundColorEvent.ROOM_COLOR, onRoomEngineEvent); + + const onRoomWidgetUpdateRoomViewEvent = useCallback((event: RoomWidgetUpdateRoomViewEvent) => + { + updateRoomBackground(); + }, [ updateRoomBackground ]); + + CreateEventDispatcherHook(RoomWidgetUpdateRoomViewEvent.SIZE_CHANGED, eventDispatcher, onRoomWidgetUpdateRoomViewEvent); + + UseMountEffect(updateRoomBackground); + + return null; +} diff --git a/src/views/room/RoomView.tsx b/src/views/room/RoomView.tsx index 2bc5e352..d55390f9 100644 --- a/src/views/room/RoomView.tsx +++ b/src/views/room/RoomView.tsx @@ -1,15 +1,16 @@ -import { EventDispatcher, Nitro, RoomEngineEvent, RoomEngineObjectEvent, RoomGeometry, RoomId, RoomObjectCategory, RoomObjectOperationType, RoomVariableEnum, Vector3d } from 'nitro-renderer'; +import { EventDispatcher, Nitro, NitroRectangle, RoomEngineEvent, RoomEngineObjectEvent, RoomGeometry, RoomId, RoomObjectCategory, RoomObjectOperationType, RoomVariableEnum, RoomZoomEvent, Vector3d } from 'nitro-renderer'; import { FC, useCallback, useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; -import { CanManipulateFurniture, IsFurnitureSelectionDisabled, ProcessRoomObjectOperation } from '../../api'; +import { CanManipulateFurniture, InitializeRoomInstanceRenderingCanvas, IsFurnitureSelectionDisabled, ProcessRoomObjectOperation } from '../../api'; import { DispatchMouseEvent } from '../../api/nitro/room/DispatchMouseEvent'; -import { WindowResizeEvent } from '../../api/nitro/room/DispatchResizeEvent'; import { DispatchTouchEvent } from '../../api/nitro/room/DispatchTouchEvent'; import { GetRoomEngine } from '../../api/nitro/room/GetRoomEngine'; import { useRoomEngineEvent } from '../../hooks/events'; import { RoomContextProvider } from './context/RoomContext'; import { RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent } from './events'; +import { RoomWidgetUpdateRoomViewEvent } from './events/RoomWidgetUpdateRoomViewEvent'; import { FurnitureContextMenuWidgetHandler, IRoomWidgetHandlerManager, RoomWidgetAvatarInfoHandler, RoomWidgetChatHandler, RoomWidgetChatInputHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler } from './handlers'; +import { RoomColorView } from './RoomColorView'; import { RoomViewProps } from './RoomView.types'; import { RoomWidgetsView } from './widgets/RoomWidgetsView'; @@ -17,6 +18,7 @@ export const RoomView: FC = props => { const { roomSession = null } = props; const [ roomCanvas, setRoomCanvas ] = useState(null); + const [ canvasId, setCanvasId ] = useState(-1); const [ widgetHandler, setWidgetHandler ] = useState(null); useEffect(() => @@ -26,6 +28,7 @@ export const RoomView: FC = props => window.onresize = null; setRoomCanvas(null); + setCanvasId(-1); setWidgetHandler(null); return; @@ -91,9 +94,22 @@ export const RoomView: FC = props => canvas.ontouchend = event => DispatchTouchEvent(roomSession.roomId, canvasId, event); canvas.ontouchcancel = event => DispatchTouchEvent(roomSession.roomId, canvasId, event); - window.onresize = event => WindowResizeEvent(roomSession.roomId, canvasId); + window.onresize = () => + { + Nitro.instance.renderer.resize(window.innerWidth, window.innerHeight); + + InitializeRoomInstanceRenderingCanvas(roomSession.roomId, canvasId, Nitro.instance.width, Nitro.instance.height); + + const bounds = canvas.getBoundingClientRect(); + const rectangle = new NitroRectangle((bounds.x || 0), (bounds.y || 0), (bounds.width || 0), (bounds.height || 0)); + + widgetHandlerManager.eventDispatcher.dispatchEvent(new RoomWidgetUpdateRoomViewEvent(RoomWidgetUpdateRoomViewEvent.SIZE_CHANGED, rectangle)); + + Nitro.instance.render(); + } setRoomCanvas(canvas); + setCanvasId(canvasId); }, [ roomSession ]); const onRoomEngineEvent = useCallback((event: RoomEngineEvent) => @@ -108,11 +124,23 @@ export const RoomView: FC = props => case RoomEngineEvent.GAME_MODE: widgetHandler.eventDispatcher.dispatchEvent(new RoomWidgetRoomEngineUpdateEvent(RoomWidgetRoomEngineUpdateEvent.GAME_MODE, event.roomId)); return; + case RoomZoomEvent.ROOM_ZOOM: { + const zoomEvent = (event as RoomZoomEvent); + + let zoomLevel = ((zoomEvent.level < 1) ? 0.5 : (1 << (Math.floor(zoomEvent.level) - 1))); + + if(zoomEvent.forceFlip || zoomEvent.asDelta) zoomLevel = zoomEvent.level; + + GetRoomEngine().setRoomInstanceRenderingCanvasScale(roomSession.roomId, 1, zoomLevel, null, null, false, zoomEvent.asDelta); + + return; + } } - }, [ widgetHandler ]); + }, [ widgetHandler, roomSession ]); useRoomEngineEvent(RoomEngineEvent.NORMAL_MODE, onRoomEngineEvent); useRoomEngineEvent(RoomEngineEvent.GAME_MODE, onRoomEngineEvent); + useRoomEngineEvent(RoomZoomEvent.ROOM_ZOOM, onRoomEngineEvent); const onRoomEngineObjectEvent = useCallback((event: RoomEngineObjectEvent) => { @@ -206,11 +234,15 @@ export const RoomView: FC = props => if(!roomSession) return null; return ( - +
{ roomCanvas && createPortal(null, document.getElementById('room-view').appendChild(roomCanvas)) } - { widgetHandler && } + { widgetHandler && + <> + + + }
); diff --git a/src/views/room/context/RoomContext.tsx b/src/views/room/context/RoomContext.tsx index 40e2417a..a4ae5222 100644 --- a/src/views/room/context/RoomContext.tsx +++ b/src/views/room/context/RoomContext.tsx @@ -3,6 +3,7 @@ import { IRoomContext, RoomContextProps } from './RoomContext.types'; const RoomContext = createContext({ roomSession: null, + canvasId: -1, eventDispatcher: null, widgetHandler: null }); diff --git a/src/views/room/context/RoomContext.types.ts b/src/views/room/context/RoomContext.types.ts index b9aade0c..3a0f4f50 100644 --- a/src/views/room/context/RoomContext.types.ts +++ b/src/views/room/context/RoomContext.types.ts @@ -5,6 +5,7 @@ import { IRoomWidgetHandlerManager } from '../handlers'; export interface IRoomContext { roomSession: IRoomSession; + canvasId: number; eventDispatcher: IEventDispatcher; widgetHandler: IRoomWidgetHandlerManager; } diff --git a/src/views/room/events/RoomWidgetUpdateRoomViewEvent.ts b/src/views/room/events/RoomWidgetUpdateRoomViewEvent.ts new file mode 100644 index 00000000..5c1b0715 --- /dev/null +++ b/src/views/room/events/RoomWidgetUpdateRoomViewEvent.ts @@ -0,0 +1,21 @@ +import { NitroRectangle } from 'nitro-renderer'; +import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; + +export class RoomWidgetUpdateRoomViewEvent extends RoomWidgetUpdateEvent +{ + public static SIZE_CHANGED: string = 'RWURVE_SIZE_CHANGED'; + + private _roomViewRectangle: NitroRectangle; + + constructor(type: string, view: NitroRectangle) + { + super(type); + + this._roomViewRectangle = view; + } + + public get roomViewRectangle(): NitroRectangle + { + return this._roomViewRectangle; + } +} diff --git a/src/views/room/widgets/RoomWidgetsView.tsx b/src/views/room/widgets/RoomWidgetsView.tsx index 57523e17..9e080424 100644 --- a/src/views/room/widgets/RoomWidgetsView.tsx +++ b/src/views/room/widgets/RoomWidgetsView.tsx @@ -1,4 +1,4 @@ -import { NitroEvent, RoomEngineUseProductEvent, RoomSessionChatEvent, RoomSessionDanceEvent, RoomSessionDimmerPresetsEvent, RoomSessionDoorbellEvent, RoomSessionErrorMessageEvent, RoomSessionEvent, RoomSessionFriendRequestEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPresentEvent, RoomSessionUserBadgesEvent } from 'nitro-renderer'; +import { NitroEvent, RoomEngineDimmerStateEvent, RoomEngineUseProductEvent, RoomSessionChatEvent, RoomSessionDanceEvent, RoomSessionDimmerPresetsEvent, RoomSessionDoorbellEvent, RoomSessionErrorMessageEvent, RoomSessionEvent, RoomSessionFriendRequestEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPresentEvent, RoomSessionUserBadgesEvent } from 'nitro-renderer'; import { FC, useCallback } from 'react'; import { useRoomEngineEvent, useRoomSessionManagerEvent } from '../../../hooks/events'; import { LocalizeText } from '../../../utils/LocalizeText'; @@ -13,7 +13,7 @@ import { RoomWidgetViewProps } from './RoomWidgets.types'; export const RoomWidgetsView: FC = props => { - const { eventDispatcher = null, widgetHandler = null } = useRoomContext(); + const { widgetHandler = null } = useRoomContext(); const onNitroEvent = useCallback((event: NitroEvent) => { @@ -35,6 +35,7 @@ export const RoomWidgetsView: FC = props => useRoomSessionManagerEvent(RoomSessionPetInfoUpdateEvent.PET_INFO, onNitroEvent); useRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY, onNitroEvent); useRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM, onNitroEvent); + useRoomEngineEvent(RoomEngineDimmerStateEvent.ROOM_COLOR, onNitroEvent); const onRoomErrorEvent = useCallback((event: RoomSessionEvent) => {