/* =========================================================================== IceTech GPL Source Code Copyright (C) 2026 Justin Marshall This file is part of the IceTech GPL Source Code. =========================================================================== */ #ifndef __MODELVIEWDOCK_H__ #define __MODELVIEWDOCK_H__ class idDeclModelDef; class idDeclModelDefInterface; class idRenderModel; class idAnim; class idMD5Anim; class idJointMat; // These IDs live in the same private range used by the XY/Game dock controls. #define ID_MODELVIEW_DECLCOMBO 0x7A60 #define ID_MODELVIEW_REFRESH 0x7A61 #define ID_MODELVIEW_SHOWSKELETON 0x7A62 #define ID_MODELVIEW_MESHTREE 0x7A63 #define ID_MODELVIEW_ANIMLIST 0x7A64 #define ID_MODELVIEW_RENDER 0x7A65 #define ID_MODELVIEW_MENUBAR 0x7A66 #define ID_MODELVIEW_FILE_NEWMD5DECL 0x7A67 #define ID_MODELVIEW_FILE_ADDANIM 0x7A68 #define ID_MODELVIEW_PLAY 0x7A69 #define ID_MODELVIEW_PAUSE 0x7A6A #define ID_MODELVIEW_STOP 0x7A6B #define ID_MODELVIEW_TIMELINE 0x7A6C #define ID_MODELVIEW_TIMETEXT 0x7A6D #define ID_MODELVIEW_TRANSPORT 0x7A6E #define ID_MODELVIEW_REIMPORT 0x7A6F #define WM_MODELVIEW_ANIMTIME_CHANGED (WM_APP + 0x260) //============================================================================= // CModelRenderWnd // // Model preview renderer for the Radiant Model View tab. // This intentionally does not own or drive the game-side animator object. // It uses the public gameEdit animation helpers that Radiant/tool code // already consumes for non-game skeletal rendering. //============================================================================= class CModelRenderWnd : public CWnd { DECLARE_DYNAMIC(CModelRenderWnd) public: CModelRenderWnd(); virtual ~CModelRenderWnd(); BOOL Create(CWnd* pParent, UINT nID); void SetModelDecl(const idDeclModelDef* modelDecl); void SetAnimation(const idMD5Anim* anim, int animLengthMS, int numFrames, const char* displayName); void SetAnimationTimeMS(int timeMS); void PlayAnimation(); void PauseAnimation(); void StopAnimation(); void SetShowSkeleton(BOOL showSkeleton); void SetActive(BOOL active); void FocusRenderWindow(); int GetAnimationTimeMS() const; int GetAnimationLengthMS() const; int GetAnimationFrames() const; BOOL HasAnimation() const; BOOL IsPlaying() const; private: HDC m_hDC; HGLRC m_hGLRC; const idDeclModelDefInterface* m_modelDecl; idRenderModel* m_model; idRenderModel* m_cachedDynamicModel; idJointMat* m_joints; int m_numJoints; BOOL m_haveAnimFrame; const idMD5Anim* m_anim; int m_animLengthMS; int m_animFrames; int m_animTimeMS; CString m_animDisplayName; DWORD m_lastTick; BOOL m_showSkeleton; BOOL m_active; BOOL m_playing; BOOL m_dragging; CPoint m_lastMouse; float m_yaw; float m_pitch; float m_distance; float m_center[3]; float m_radius; private: void InitGL(); void ShutdownGL(); void FreeJointBuffer(); void AllocateJointBuffer(); void ResetCachedDynamicModel(); void ResolveModelFromGameEdit(); void UpdateAnimationFrame(BOOL forceResetCachedModel); void NotifyAnimationTimeChanged(); void FitCameraToModel(); void StepAnimation(); void DrawScene(); void SetupCamera(const CRect& client); void DrawGrid(); void DrawModel(); void DrawRenderModel(idRenderModel* model, bool wireOnly); void DrawSkeleton(); void DrawOverlayText(); protected: afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnDestroy(); afx_msg void OnPaint(); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnTimer(UINT_PTR nIDEvent); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); DECLARE_MESSAGE_MAP() }; //============================================================================= // CModelViewDockWnd //============================================================================= class CModelViewDockWnd : public CWnd { DECLARE_DYNAMIC(CModelViewDockWnd) public: CModelViewDockWnd(); virtual ~CModelViewDockWnd(); BOOL Create(CWnd* pParent, UINT nID); void LayoutChildren(); void SetActive(BOOL active); void FocusModelView(); private: CStatic m_lblModel; CComboBox m_comboDecls; CButton m_btnRefresh; CButton m_btnReimport; CButton m_chkSkeleton; CStatic m_lblMesh; CStatic m_lblAnim; CTreeCtrl m_treeMesh; CListBox m_listAnims; CModelRenderWnd m_wndRender; CStatic m_transportPanel; CButton m_btnPlay; CButton m_btnPause; CButton m_btnStop; CSliderCtrl m_sliderTimeline; CStatic m_lblTime; HWND m_hMenuBar; const idDeclModelDefInterface* m_modelDecl; BOOL m_active; bool m_inLayout; bool m_updatingTimeline; int m_timelineLengthMS; CPtrArray m_animItems; private: void ApplyDarkTheme(); void ClearAnimationItems(); void PopulateModelDecls(); void LoadSelectedModelDecl(); CString GetSelectedModelDeclFileName(); void SetModelDecl(const idDeclModelDef* modelDecl); void PopulateMeshTree(); void PopulateAnimationList(); void SelectAnimationItem(int itemIndex); void SelectModelDeclByName(const char* declName); void SelectAnimationByName(const char* animName); void SetTimelineRange(int animLengthMS); void UpdateTimelinePosition(int animTimeMS, int animLengthMS); void UpdateTimeLabel(int animTimeMS, int animLengthMS); void UpdateTransportControls(); protected: afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct); afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct); afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); afx_msg void OnDeclChanged(); afx_msg void OnAnimChanged(); afx_msg void OnRefresh(); afx_msg void OnReimportModel(); afx_msg void OnNewMD5Decl(); afx_msg void OnAddAnimationFile(); afx_msg void OnShowSkeleton(); afx_msg void OnPlay(); afx_msg void OnPause(); afx_msg void OnStop(); afx_msg LRESULT OnAnimTimeChanged(WPARAM wParam, LPARAM lParam); DECLARE_MESSAGE_MAP() }; #endif // __MODELVIEWDOCK_H__