Files
DoomRTX/neo/engine/tools/radiant/ModelViewDock.h
T

302 lines
10 KiB
C++

/*
===========================================================================
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 idMaterial;
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_SHOWPLAYERMESH 0x7A7F
#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 ID_MODELVIEW_FILE_IMPORTSTATICMESH 0x7A70
#define ID_MODELVIEW_FILE_EXPORTMD5STATIC 0x7A72
#define ID_MODELVIEW_SURFACEMATS 0x7A73
#define ID_MODELVIEW_SETMATERIAL 0x7A74
#define ID_MODELVIEW_CLEARMATERIAL 0x7A75
#define ID_MODELVIEW_TRANSFORM_TX 0x7A76
#define ID_MODELVIEW_TRANSFORM_TY 0x7A77
#define ID_MODELVIEW_TRANSFORM_TZ 0x7A78
#define ID_MODELVIEW_TRANSFORM_RX 0x7A79
#define ID_MODELVIEW_TRANSFORM_RY 0x7A7A
#define ID_MODELVIEW_TRANSFORM_RZ 0x7A7B
#define ID_MODELVIEW_TRANSFORM_SX 0x7A7C
#define ID_MODELVIEW_TRANSFORM_SY 0x7A7D
#define ID_MODELVIEW_TRANSFORM_SZ 0x7A7E
#define ID_MODELVIEW_INVERTNORMALS 0x7A80
#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 SetStandaloneModel(idRenderModel* model, const char* displayName);
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 SetShowPlayerMesh(BOOL showPlayerMesh);
void SetActive(BOOL active);
void FocusRenderWindow();
int GetAnimationTimeMS() const;
int GetAnimationLengthMS() const;
int GetAnimationFrames() const;
BOOL HasAnimation() const;
BOOL IsPlaying() const;
idRenderModel* CurrentModel() const;
const idMaterial* SurfaceMaterialForSurface(int surfaceNum, const idMaterial* fallback) const;
const idMaterial* SurfaceMaterialOverride(int surfaceNum) const;
void SetSurfaceMaterialOverride(int surfaceNum, const idMaterial* material);
void ClearSurfaceMaterialOverride(int surfaceNum);
void ClearSurfaceMaterialOverrides();
void SetStaticTransform(const idVec3& translate, const idVec3& rotate, const idVec3& scale);
void ResetStaticTransform();
bool InvertCurrentModelNormals();
bool WriteCurrentMD5Static(const char* fileName) const;
private:
HDC m_hDC;
HGLRC m_hGLRC;
const idDeclModelDefInterface* m_modelDecl;
idRenderModel* m_model;
idRenderModel* m_cachedDynamicModel;
const idDeclModelDefInterface* m_playerModelDecl;
idRenderModel* m_playerModel;
idRenderModel* m_cachedPlayerModel;
idJointMat* m_joints;
idJointMat* m_playerJoints;
int m_numJoints;
int m_numPlayerJoints;
BOOL m_haveAnimFrame;
BOOL m_havePlayerFrame;
const idMD5Anim* m_anim;
int m_animLengthMS;
int m_animFrames;
int m_animTimeMS;
CString m_animDisplayName;
CString m_standaloneDisplayName;
idList<const idMaterial*> m_surfaceMaterialOverrides;
idVec3 m_staticTranslate;
idVec3 m_staticRotate;
idVec3 m_staticScale;
DWORD m_lastTick;
BOOL m_showSkeleton;
BOOL m_showPlayerMesh;
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 FreePlayerJointBuffer();
void AllocateJointBuffer();
void ResetCachedDynamicModel();
void ResetCachedPlayerModel();
void ResolveModelFromGameEdit();
void ResolvePlayerReferenceModel();
void UpdateAnimationFrame(BOOL forceResetCachedModel);
void UpdatePlayerReferenceFrame(BOOL forceResetCachedModel);
void NotifyAnimationTimeChanged();
void FitCameraToModel();
idVec3 PlayerReferenceOffset(idRenderModel* drawModel) const;
void StepAnimation();
void DrawScene();
void SetupCamera(const CRect& client);
void DrawGrid();
void DrawModel();
void DrawPlayerReferenceModel(idRenderModel* drawModel);
void DrawRenderModel(idRenderModel* model, bool wireOnly, bool useMaterialOverrides = true, bool applyStaticTransform = true);
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;
CButton m_chkPlayerMesh;
CButton m_btnInvertNormals;
CStatic m_lblMesh;
CStatic m_lblStaticTransform;
CStatic m_lblTransformCols[3];
CStatic m_lblTransformRows[3];
CEdit m_editTransform[3][3];
CStatic m_lblSurfaceMaterials;
CStatic m_lblAnim;
CTreeCtrl m_treeMesh;
CListBox m_listSurfaceMaterials;
CButton m_btnSetSurfaceMaterial;
CButton m_btnClearSurfaceMaterial;
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;
idRenderModel* m_importedModel;
CString m_importedModelPath;
bool m_importedIsOBJ;
bool m_importedIsMD5Static;
BOOL m_active;
bool m_inLayout;
bool m_updatingTimeline;
bool m_updatingStaticTransform;
int m_timelineLengthMS;
CPtrArray m_animItems;
private:
void ApplyDarkTheme();
void RedrawDarkControls();
void ClearAnimationItems();
void PopulateModelDecls();
void LoadSelectedModelDecl();
void ClearImportedModel();
CString GetSelectedModelDeclFileName();
void SetModelDecl(const idDeclModelDef* modelDecl);
void PopulateStandaloneModelTree(idRenderModel* model, const char* displayName);
void PopulateMeshTree();
bool CurrentPreviewModelIsStatic() const;
void ResetStaticTransformControls();
void UpdateStaticTransformControls();
void ReadStaticTransformControls();
void PopulateSurfaceMaterialList();
idRenderModel* CurrentPreviewModel() const;
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 OnSurfaceMaterialChanged();
afx_msg void OnStaticTransformChanged();
afx_msg void OnSetSurfaceMaterial();
afx_msg void OnClearSurfaceMaterial();
afx_msg void OnRefresh();
afx_msg void OnReimportModel();
afx_msg void OnNewMD5Decl();
afx_msg void OnImportStaticMesh();
afx_msg void OnExportMD5Static();
afx_msg void OnAddAnimationFile();
afx_msg void OnShowSkeleton();
afx_msg void OnShowPlayerMesh();
afx_msg void OnInvertNormals();
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__