1001 lines
26 KiB
C++
1001 lines
26 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
// MainFrm.cpp : implementation of the CMainFrame class
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "PhysTest.h"
|
|
|
|
#include "MainFrm.h"
|
|
#include "PhysTestDoc.h"
|
|
#include "GraphicView.h"
|
|
#include "DataView.h"
|
|
#include "PhysicsConstantsDialog.h"
|
|
#include "VJoyDialog.h"
|
|
#include "InertiaDialog.h"
|
|
#include "RbodyPropertiesDialog.h"
|
|
#include "MotorVehicleDialog.h"
|
|
#include "WheeledVehicleDialog.h"
|
|
#include "MotorcycleDialog.h"
|
|
#include "RenderDeviceDialog.h"
|
|
#include "assetmgr.h"
|
|
#include "ww3d.h"
|
|
#include "part_ldr.h"
|
|
#include "pscene.h"
|
|
#include "rbody.h"
|
|
#include "motorvehicle.h"
|
|
#include "wheelvehicle.h"
|
|
#include "motorcycle.h"
|
|
#include "chunkio.h"
|
|
|
|
const float IMPULSE_SCALE = 3.0f;
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMainFrame CHUNK Id's
|
|
enum {
|
|
MAINFRAME_CHUNK_VARIABLES = 0x00800760,
|
|
MAINFRAME_CHUNK_TREEVIEW,
|
|
MAINFRAME_CHUNK_GRAPHICVIEW,
|
|
MAINFRAME_VARIABLE_CONTROLLERPTR = 0x00,
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMainFrame
|
|
|
|
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
|
|
|
|
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
|
|
//{{AFX_MSG_MAP(CMainFrame)
|
|
ON_WM_CREATE()
|
|
ON_WM_ACTIVATEAPP()
|
|
ON_COMMAND(ID_OPTIONS_RUN_SIMULATION, OnOptionsRunSimulation)
|
|
ON_UPDATE_COMMAND_UI(ID_OPTIONS_RUN_SIMULATION, OnUpdateOptionsRunSimulation)
|
|
ON_COMMAND(ID_OPTIONS_DISPLAY_BOXES, OnOptionsDisplayBoxes)
|
|
ON_UPDATE_COMMAND_UI(ID_OPTIONS_DISPLAY_BOXES, OnUpdateOptionsDisplayBoxes)
|
|
ON_COMMAND(ID_CREATE_RIGID_BODY, OnCreateRigidBody)
|
|
ON_UPDATE_COMMAND_UI(ID_COUPLE_NEGX, OnUpdateImpulseButton)
|
|
ON_COMMAND(ID_COUPLE_NEGX, OnCoupleNegx)
|
|
ON_COMMAND(ID_COUPLE_NEGY, OnCoupleNegy)
|
|
ON_COMMAND(ID_COUPLE_NEGZ, OnCoupleNegz)
|
|
ON_COMMAND(ID_COUPLE_POSX, OnCouplePosx)
|
|
ON_COMMAND(ID_COUPLE_POSY, OnCouplePosy)
|
|
ON_COMMAND(ID_COUPLE_POSZ, OnCouplePosz)
|
|
ON_COMMAND(ID_IMPULSE_NEGX, OnImpulseNegx)
|
|
ON_COMMAND(ID_IMPULSE_NEGY, OnImpulseNegy)
|
|
ON_COMMAND(ID_IMPULSE_NEGZ, OnImpulseNegz)
|
|
ON_COMMAND(ID_IMPULSE_POSX, OnImpulsePosx)
|
|
ON_COMMAND(ID_IMPULSE_POSY, OnImpulsePosy)
|
|
ON_COMMAND(ID_IMPULSE_POSZ, OnImpulsePosz)
|
|
ON_COMMAND(ID_VIEW_IMPULSETOOLBAR, OnViewImpulsetoolbar)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_IMPULSETOOLBAR, OnUpdateViewImpulsetoolbar)
|
|
ON_COMMAND(ID_PROPERTIES, OnProperties)
|
|
ON_COMMAND(ID_INERTIA, OnInertia)
|
|
ON_COMMAND(ID_OPTIONS_PHYSICS_CONSTANTS, OnOptionsPhysicsConstants)
|
|
ON_COMMAND(ID_FREEZE_OBJECT, OnFreezeObject)
|
|
ON_COMMAND(ID_DEBUG_OBJECT, OnDebugObject)
|
|
ON_UPDATE_COMMAND_UI(ID_DEBUG_OBJECT, OnUpdateDebugObject)
|
|
ON_COMMAND(ID_VIEW_VIRTUALJOYSTICK, OnViewVirtualjoystick)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_VIRTUALJOYSTICK, OnUpdateViewVirtualjoystick)
|
|
ON_WM_DESTROY()
|
|
ON_COMMAND(ID_OPTIONS_FILLED, OnOptionsFilled)
|
|
ON_UPDATE_COMMAND_UI(ID_OPTIONS_FILLED, OnUpdateOptionsFilled)
|
|
ON_COMMAND(ID_OPTIONS_POINTS, OnOptionsPoints)
|
|
ON_UPDATE_COMMAND_UI(ID_OPTIONS_POINTS, OnUpdateOptionsPoints)
|
|
ON_COMMAND(ID_OPTIONS_WIREFRAME, OnOptionsWireframe)
|
|
ON_UPDATE_COMMAND_UI(ID_OPTIONS_WIREFRAME, OnUpdateOptionsWireframe)
|
|
ON_COMMAND(ID_MOTOR_PROPERTIES, OnMotorProperties)
|
|
ON_COMMAND(ID_WHEEL_PROPERTIES, OnWheelProperties)
|
|
ON_UPDATE_COMMAND_UI(ID_WHEEL_PROPERTIES, OnUpdateWheelProperties)
|
|
ON_UPDATE_COMMAND_UI(ID_MOTOR_PROPERTIES, OnUpdateMotorProperties)
|
|
ON_COMMAND(ID_CAMERA_FOLLOW, OnCameraFollow)
|
|
ON_UPDATE_COMMAND_UI(ID_CAMERA_FOLLOW, OnUpdateCameraFollow)
|
|
ON_COMMAND(ID_CAMERA_FLY, OnCameraFly)
|
|
ON_UPDATE_COMMAND_UI(ID_CAMERA_FLY, OnUpdateCameraFly)
|
|
ON_COMMAND(ID_CAMERA_TETHER, OnCameraTether)
|
|
ON_UPDATE_COMMAND_UI(ID_CAMERA_TETHER, OnUpdateCameraTether)
|
|
ON_COMMAND(ID_CAMERA_RIGID_TETHER, OnCameraRigidTether)
|
|
ON_UPDATE_COMMAND_UI(ID_CAMERA_RIGID_TETHER, OnUpdateCameraRigidTether)
|
|
ON_COMMAND(ID_CREATE_WHEELED_VEHICLE, OnCreateWheeledVehicle)
|
|
ON_UPDATE_COMMAND_UI(ID_CREATE_RIGID_BODY, OnUpdateCreateRigidBody)
|
|
ON_UPDATE_COMMAND_UI(ID_CREATE_WHEELED_VEHICLE, OnUpdateCreateWheeledVehicle)
|
|
ON_UPDATE_COMMAND_UI(ID_PROPERTIES, OnUpdateProperties)
|
|
ON_COMMAND(ID_CREATE_MOTORCYCLE, OnCreateMotorcycle)
|
|
ON_UPDATE_COMMAND_UI(ID_CREATE_MOTORCYCLE, OnUpdateCreateMotorcycle)
|
|
ON_COMMAND(ID_MOTORCYCLE_PROPERTIES, OnMotorcycleProperties)
|
|
ON_UPDATE_COMMAND_UI(ID_MOTORCYCLE_PROPERTIES, OnUpdateMotorcycleProperties)
|
|
ON_COMMAND(ID_OPTIONS_RENDER_DEVICE, OnOptionsRenderDevice)
|
|
ON_UPDATE_COMMAND_UI(ID_OPTIONS_RENDER_DEVICE, OnUpdateOptionsRenderDevice)
|
|
ON_COMMAND(ID_FILE_IMPORT_MODEL, OnFileImportModel)
|
|
ON_COMMAND(ID_FILE_IMPORT_LEV, OnFileImportLev)
|
|
ON_UPDATE_COMMAND_UI(ID_COUPLE_NEGY, OnUpdateImpulseButton)
|
|
ON_UPDATE_COMMAND_UI(ID_COUPLE_NEGZ, OnUpdateImpulseButton)
|
|
ON_UPDATE_COMMAND_UI(ID_COUPLE_POSX, OnUpdateImpulseButton)
|
|
ON_UPDATE_COMMAND_UI(ID_COUPLE_POSY, OnUpdateImpulseButton)
|
|
ON_UPDATE_COMMAND_UI(ID_COUPLE_POSZ, OnUpdateImpulseButton)
|
|
ON_UPDATE_COMMAND_UI(ID_IMPULSE_NEGX, OnUpdateImpulseButton)
|
|
ON_UPDATE_COMMAND_UI(ID_IMPULSE_NEGY, OnUpdateImpulseButton)
|
|
ON_UPDATE_COMMAND_UI(ID_IMPULSE_NEGZ, OnUpdateImpulseButton)
|
|
ON_UPDATE_COMMAND_UI(ID_IMPULSE_POSX, OnUpdateImpulseButton)
|
|
ON_UPDATE_COMMAND_UI(ID_IMPULSE_POSY, OnUpdateImpulseButton)
|
|
ON_UPDATE_COMMAND_UI(ID_IMPULSE_POSZ, OnUpdateImpulseButton)
|
|
ON_UPDATE_COMMAND_UI(ID_INERTIA, OnUpdateImpulseButton)
|
|
ON_UPDATE_COMMAND_UI(ID_FREEZE_OBJECT, OnUpdateImpulseButton)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
static UINT indicators[] =
|
|
{
|
|
ID_SEPARATOR, // status line indicator
|
|
ID_INDICATOR_CAPS,
|
|
ID_INDICATOR_NUM,
|
|
ID_INDICATOR_SCRL,
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMainFrame construction/destruction
|
|
|
|
CMainFrame::CMainFrame() :
|
|
VirtualJoystick(NULL),
|
|
ControlledObject(NULL)
|
|
{
|
|
}
|
|
|
|
CMainFrame::~CMainFrame()
|
|
{
|
|
REF_PTR_RELEASE(ControlledObject);
|
|
}
|
|
|
|
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
|
|
{
|
|
if( !CFrameWnd::PreCreateWindow(cs) )
|
|
return FALSE;
|
|
// TODO: Modify the Window class or styles here by modifying
|
|
// the CREATESTRUCT cs
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
|
|
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
|
|
!m_wndToolBar.LoadToolBar(IDR_MAINTOOLBAR))
|
|
{
|
|
TRACE0("Failed to create toolbar\n");
|
|
return -1; // fail to create
|
|
}
|
|
|
|
if (!m_wndImpulseToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
|
|
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
|
|
!m_wndImpulseToolBar.LoadToolBar(IDR_IMPULSE_TOOLBAR))
|
|
{
|
|
TRACE0("Failed to create impulse toolbar\n");
|
|
return -1; // fail to create
|
|
}
|
|
|
|
if (!m_wndStatusBar.Create(this) ||
|
|
!m_wndStatusBar.SetIndicators(indicators,
|
|
sizeof(indicators)/sizeof(UINT)))
|
|
{
|
|
TRACE0("Failed to create status bar\n");
|
|
return -1; // fail to create
|
|
}
|
|
|
|
// Make the toolbar dockable
|
|
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
|
|
m_wndImpulseToolBar.EnableDocking(CBRS_ALIGN_ANY);
|
|
EnableDocking(CBRS_ALIGN_ANY);
|
|
DockControlBar(&m_wndToolBar);
|
|
DockControlBar(&m_wndImpulseToolBar);
|
|
|
|
// Make sure load on demand is activated
|
|
WW3DAssetManager::Get_Instance()->Set_WW3D_Load_On_Demand (true);
|
|
|
|
// Create the virtual joystick dialog
|
|
VirtualJoystick = new CVJoyDialog;
|
|
VirtualJoystick->Create(IDD_VJOY_DIALOG,this);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CMainFrame::OnDestroy()
|
|
{
|
|
CFrameWnd::OnDestroy();
|
|
|
|
if (VirtualJoystick != NULL) {
|
|
VirtualJoystick->DestroyWindow();
|
|
delete VirtualJoystick;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMainFrame Save/Load
|
|
|
|
void CMainFrame::Save(ChunkSaveClass & csave)
|
|
{
|
|
PhysControllerClass * controlptr = &(VirtualJoystick->Controller);
|
|
csave.Begin_Chunk(MAINFRAME_CHUNK_VARIABLES);
|
|
WRITE_MICRO_CHUNK(csave,MAINFRAME_VARIABLE_CONTROLLERPTR,controlptr);
|
|
csave.End_Chunk();
|
|
|
|
csave.Begin_Chunk(MAINFRAME_CHUNK_TREEVIEW);
|
|
CDataView * data_view = (CDataView *)Splitter.GetPane(0,0);
|
|
data_view->Save(csave);
|
|
csave.End_Chunk();
|
|
|
|
csave.Begin_Chunk(MAINFRAME_CHUNK_GRAPHICVIEW);
|
|
CGraphicView * graphic_view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
graphic_view->Save(csave);
|
|
csave.End_Chunk();
|
|
}
|
|
|
|
void CMainFrame::Load(ChunkLoadClass & cload)
|
|
{
|
|
PhysControllerClass * controlptr = NULL;
|
|
CGraphicView * graphic_view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
CDataView * data_view = (CDataView *)Splitter.GetPane(0,0);
|
|
|
|
while (cload.Open_Chunk()) {
|
|
switch (cload.Cur_Chunk_ID()) {
|
|
case MAINFRAME_CHUNK_VARIABLES:
|
|
while (cload.Open_Micro_Chunk()) {
|
|
switch(cload.Cur_Micro_Chunk_ID()) {
|
|
READ_MICRO_CHUNK(cload,MAINFRAME_VARIABLE_CONTROLLERPTR,controlptr);
|
|
}
|
|
cload.Close_Micro_Chunk();
|
|
}
|
|
break;
|
|
|
|
case MAINFRAME_CHUNK_TREEVIEW:
|
|
data_view->Load(cload);
|
|
break;
|
|
|
|
case MAINFRAME_CHUNK_GRAPHICVIEW:
|
|
graphic_view->Load(cload);
|
|
break;
|
|
}
|
|
cload.Close_Chunk();
|
|
}
|
|
|
|
if (controlptr != NULL) {
|
|
SaveLoadSystemClass::Register_Pointer(controlptr,&(VirtualJoystick->Controller));
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMainFrame diagnostics
|
|
|
|
#ifdef _DEBUG
|
|
void CMainFrame::AssertValid() const
|
|
{
|
|
CFrameWnd::AssertValid();
|
|
}
|
|
|
|
void CMainFrame::Dump(CDumpContext& dc) const
|
|
{
|
|
CFrameWnd::Dump(dc);
|
|
}
|
|
|
|
#endif //_DEBUG
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMainFrame message handlers
|
|
|
|
|
|
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
|
|
{
|
|
// Create the main splitter window for the application
|
|
BOOL ok = Splitter.CreateStatic (this, 1, 2);
|
|
ASSERT(ok);
|
|
if (!ok) return FALSE;
|
|
|
|
// Create the two views
|
|
ok &= Splitter.CreateView(0,0,RUNTIME_CLASS(CDataView),CSize(200,10),pContext);
|
|
ok &= Splitter.CreateView(0,1,RUNTIME_CLASS(CGraphicView),CSize(340,10),pContext);
|
|
|
|
ASSERT(ok);
|
|
if (!ok) return FALSE;
|
|
|
|
CGraphicView * view = (CGraphicView *)Splitter.GetPane(0, 1);
|
|
ASSERT(view != NULL);
|
|
if (view == NULL) return FALSE;
|
|
|
|
// Set the current directory to the application's run directory.
|
|
TCHAR szFileName[MAX_PATH];
|
|
::GetModuleFileName (NULL, szFileName, sizeof (szFileName));
|
|
LPTSTR pszPath = ::strrchr (szFileName, '\\');
|
|
if (pszPath)
|
|
{
|
|
pszPath[0] = 0;
|
|
::SetCurrentDirectory (szFileName);
|
|
}
|
|
|
|
// Initialize WW3D using the window handle for the graphic view
|
|
ok = (WW3D::Init((HWND)*view) == WW3D_ERROR_OK);
|
|
ASSERT(ok);
|
|
if (!ok) return FALSE;
|
|
|
|
#if 0
|
|
// Show a dialog to the user asking them which
|
|
// device they would like to use.
|
|
CDeviceSelectionDialog deviceSelDialog;
|
|
|
|
if (deviceSelDialog.DoModal () == IDOK) {
|
|
|
|
// Record the user's selection from the dialog
|
|
int device = deviceSelDialog.GetDeviceIndex();
|
|
int bits = deviceSelDialog.GetBitsPerPixel();
|
|
|
|
// Ask the view to initialize itself with the graphics engine
|
|
bool ok = view->Initialize_WW3D(device,bits);
|
|
ASSERT(ok);
|
|
|
|
} else {
|
|
|
|
// Stop the application from running
|
|
return FALSE;
|
|
|
|
}
|
|
#else
|
|
view->Initialize_WW3D(0,16);
|
|
#endif
|
|
|
|
// Register any needed loaders
|
|
WW3DAssetManager::Get_Instance()->Register_Prototype_Loader (&_ParticleEmitterLoader);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CMainFrame::OnActivateApp(BOOL bActive, HTASK hTask)
|
|
{
|
|
// Get a pointer to the 'graphic' pane's window
|
|
CGraphicView * view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
|
|
// Were we successful in view's getting the pointer?
|
|
ASSERT(view);
|
|
if (view) {
|
|
// Let the view know whether or not to actively update
|
|
// its display (animation, etc)
|
|
view->Set_Active(bActive == TRUE);
|
|
}
|
|
|
|
// Allow the base class to process this message
|
|
CFrameWnd::OnActivateApp(bActive, hTask);
|
|
return ;
|
|
}
|
|
|
|
void CMainFrame::OnOptionsRunSimulation()
|
|
{
|
|
CGraphicView * view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
ASSERT(view);
|
|
if (view) {
|
|
view->Enable_Simulation(!view->Is_Simulation_Enabled());
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnUpdateOptionsRunSimulation(CCmdUI* pCmdUI)
|
|
{
|
|
CGraphicView * view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
ASSERT(view);
|
|
|
|
if (view) {
|
|
pCmdUI->SetCheck(view->Is_Simulation_Enabled());
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnOptionsDisplayBoxes()
|
|
{
|
|
CGraphicView * view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
ASSERT(view);
|
|
if (view) {
|
|
view->Enable_Collision_Box_Display(!view->Is_Collision_Box_Display_Enabled());
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnUpdateOptionsDisplayBoxes(CCmdUI* pCmdUI)
|
|
{
|
|
CGraphicView * view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
ASSERT(view);
|
|
|
|
if (view) {
|
|
pCmdUI->SetCheck(view->Is_Collision_Box_Display_Enabled());
|
|
}
|
|
}
|
|
|
|
void CMainFrame::Add_Object(PhysClass * new_obj)
|
|
{
|
|
CPhysTestDoc * doc = Get_Document();
|
|
|
|
new_obj->Set_Transform(Matrix3D(1));
|
|
new_obj->Set_Collision_Group(0);
|
|
new_obj->Enable_Debug_Display(true);
|
|
|
|
CString name;
|
|
name.Format("%s_%2d",new_obj->Peek_Model()->Get_Name(),doc->Get_Physics_Object_Count());
|
|
new_obj->Set_Name(name);
|
|
|
|
if (doc != NULL) {
|
|
doc->Add_Physics_Object(new_obj);
|
|
}
|
|
}
|
|
|
|
CPhysTestDoc * CMainFrame::Get_Document(void)
|
|
{
|
|
CDataView * data_view = (CDataView *)Splitter.GetPane(0,0);
|
|
CPhysTestDoc * doc = (CPhysTestDoc *)data_view->GetDocument();
|
|
return doc;
|
|
}
|
|
|
|
void CMainFrame::OnCreateRigidBody()
|
|
{
|
|
const char * model_name = Peek_Selected_Model();
|
|
if (model_name == NULL) return;
|
|
|
|
RenderObjClass * model = WW3DAssetManager::Get_Instance()->Create_Render_Obj(model_name);
|
|
if (model == NULL) return;
|
|
|
|
RigidBodyClass * obj = NEW_REF(RigidBodyClass,());
|
|
obj->Set_Model(model);
|
|
obj->Enable_Shadow_Generation(true);
|
|
|
|
Add_Object(obj);
|
|
obj->Release_Ref();
|
|
model->Release_Ref();
|
|
}
|
|
|
|
void CMainFrame::OnUpdateCreateRigidBody(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(Peek_Selected_Model() != NULL);
|
|
}
|
|
|
|
void CMainFrame::OnCreateWheeledVehicle()
|
|
{
|
|
const char * model_name = Peek_Selected_Model();
|
|
if (model_name == NULL) return;
|
|
|
|
RenderObjClass * model = WW3DAssetManager::Get_Instance()->Create_Render_Obj(model_name);
|
|
if (model == NULL) return;
|
|
|
|
WheeledVehicleClass * obj = NEW_REF(WheeledVehicleClass,());
|
|
obj->Set_Model(model);
|
|
obj->Enable_Shadow_Generation(true);
|
|
|
|
Add_Object(obj);
|
|
obj->Release_Ref();
|
|
model->Release_Ref();
|
|
}
|
|
|
|
void CMainFrame::OnUpdateCreateWheeledVehicle(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(Peek_Selected_Model() != NULL);
|
|
}
|
|
|
|
void CMainFrame::OnCreateMotorcycle()
|
|
{
|
|
const char * model_name = Peek_Selected_Model();
|
|
if (model_name == NULL) return;
|
|
|
|
RenderObjClass * model = WW3DAssetManager::Get_Instance()->Create_Render_Obj(model_name);
|
|
if (model == NULL) return;
|
|
|
|
MotorcycleClass * obj = NEW_REF(MotorcycleClass,());
|
|
obj->Set_Model(model);
|
|
obj->Enable_Shadow_Generation(true);
|
|
|
|
Add_Object(obj);
|
|
obj->Release_Ref();
|
|
model->Release_Ref();
|
|
}
|
|
|
|
void CMainFrame::OnUpdateCreateMotorcycle(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(Peek_Selected_Model() != NULL);
|
|
}
|
|
|
|
const char * CMainFrame::Peek_Selected_Model(void)
|
|
{
|
|
CDataView * data_view = (CDataView *)Splitter.GetPane(0,0);
|
|
CPhysTestDoc * doc = (CPhysTestDoc *)data_view->GetDocument();
|
|
if ((data_view == NULL) || (doc == NULL)) return NULL;
|
|
|
|
// get the currently selected instance
|
|
ItemInfoClass * item = data_view->Get_Selected_Item();
|
|
if (item == NULL) return NULL;
|
|
if (item->Type != ItemInfoClass::MODEL) return NULL;
|
|
|
|
return item->Name;
|
|
}
|
|
|
|
|
|
PhysClass * CMainFrame::Peek_Selected_Object(void)
|
|
{
|
|
CDataView * data_view = (CDataView *)Splitter.GetPane(0,0);
|
|
CPhysTestDoc * doc = (CPhysTestDoc *)data_view->GetDocument();
|
|
if ((data_view == NULL) || (doc == NULL)) return NULL;
|
|
|
|
// get the currently selected instance
|
|
ItemInfoClass * item = data_view->Get_Selected_Item();
|
|
if (item == NULL) return NULL;
|
|
if (item->Type != ItemInfoClass::INSTANCE) return NULL;
|
|
|
|
PhysClass * obj = (PhysClass *)item->Instance;
|
|
return obj;
|
|
}
|
|
|
|
MoveablePhysClass * CMainFrame::Peek_Selected_MoveablePhysClass(void)
|
|
{
|
|
PhysClass * obj = Peek_Selected_Object();
|
|
if (obj) {
|
|
return obj->As_MoveablePhysClass();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
RigidBodyClass * CMainFrame::Peek_Selected_RigidBodyClass(void)
|
|
{
|
|
PhysClass * obj = Peek_Selected_Object();
|
|
if (obj) {
|
|
return obj->As_RigidBodyClass();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
MotorVehicleClass * CMainFrame::Peek_Selected_MotorVehicleClass(void)
|
|
{
|
|
PhysClass * obj = Peek_Selected_Object();
|
|
if (obj) {
|
|
return obj->As_MotorVehicleClass();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
WheeledVehicleClass * CMainFrame::Peek_Selected_WheeledVehicleClass(void)
|
|
{
|
|
PhysClass * obj = Peek_Selected_Object();
|
|
if (obj) {
|
|
return obj->As_WheeledVehicleClass();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
MotorcycleClass * CMainFrame::Peek_Selected_MotorcycleClass(void)
|
|
{
|
|
PhysClass * obj = Peek_Selected_Object();
|
|
if (obj) {
|
|
return obj->As_MotorcycleClass();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void CMainFrame::Apply_Impulse(const Vector3 & imp)
|
|
{
|
|
RigidBodyClass * rbody = Peek_Selected_RigidBodyClass();
|
|
if (rbody) {
|
|
// impulses were "tuned" to work with a 1kg object, so scale by the mass
|
|
rbody->Apply_Impulse(rbody->Get_Mass() * IMPULSE_SCALE * imp);
|
|
}
|
|
}
|
|
|
|
void CMainFrame::Apply_Couple(const Vector3 & p0,const Vector3 & i0,const Vector3 & p1,const Vector3 & i1)
|
|
{
|
|
RigidBodyClass * rbody = Peek_Selected_RigidBodyClass();
|
|
if (rbody) {
|
|
// impulses were "tuned" to work with a 1kg object, so scale by the mass
|
|
Vector3 pos = rbody->Get_Transform().Get_Translation() + p0;
|
|
rbody->Apply_Impulse(rbody->Get_Mass() * IMPULSE_SCALE * i0,pos);
|
|
|
|
pos = rbody->Get_Transform().Get_Translation() + p1;
|
|
rbody->Apply_Impulse(rbody->Get_Mass() * IMPULSE_SCALE * i1,pos);
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnUpdateImpulseButton(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(Peek_Selected_RigidBodyClass() != NULL);
|
|
}
|
|
|
|
void CMainFrame::OnCoupleNegx()
|
|
{
|
|
Apply_Couple( Vector3( 0, 1, 0), // p0
|
|
Vector3( 0, 0, 1), // i0
|
|
Vector3( 0,-1, 0), // p1
|
|
Vector3( 0, 0,-1) // i1
|
|
);
|
|
}
|
|
|
|
void CMainFrame::OnCoupleNegy()
|
|
{
|
|
Apply_Couple( Vector3( 1, 0, 0), // p0
|
|
Vector3( 0, 0, 1), // i0
|
|
Vector3(-1, 0, 0), // p1
|
|
Vector3( 0, 0,-1) // i1
|
|
);
|
|
}
|
|
|
|
void CMainFrame::OnCoupleNegz()
|
|
{
|
|
Apply_Couple( Vector3( 0, 1, 0), // p0
|
|
Vector3( 1, 0, 0), // i0
|
|
Vector3( 0,-1, 0), // p1
|
|
Vector3(-1, 0, 0) // i1
|
|
);
|
|
}
|
|
|
|
void CMainFrame::OnCouplePosx()
|
|
{
|
|
Apply_Couple( Vector3( 0,-1, 0), // p0
|
|
Vector3( 0, 0, 1), // i0
|
|
Vector3( 0, 1, 0), // p1
|
|
Vector3( 0, 0,-1) // i1
|
|
);
|
|
}
|
|
|
|
void CMainFrame::OnCouplePosy()
|
|
{
|
|
Apply_Couple( Vector3( 1, 0, 0), // p0
|
|
Vector3( 0, 0,-1), // i0
|
|
Vector3(-1, 0, 0), // p1
|
|
Vector3( 0, 0, 1) // i1
|
|
);
|
|
}
|
|
|
|
void CMainFrame::OnCouplePosz()
|
|
{
|
|
Apply_Couple( Vector3( 0, 1, 0), // p0
|
|
Vector3(-1, 0, 0), // i0
|
|
Vector3( 0,-1, 0), // p1
|
|
Vector3( 1, 0, 0) // i1
|
|
);
|
|
}
|
|
|
|
void CMainFrame::OnImpulseNegx()
|
|
{
|
|
Apply_Impulse(Vector3(-1,0,0));
|
|
}
|
|
|
|
void CMainFrame::OnImpulseNegy()
|
|
{
|
|
Apply_Impulse(Vector3(0,-1,0));
|
|
}
|
|
|
|
void CMainFrame::OnImpulseNegz()
|
|
{
|
|
Apply_Impulse(Vector3(0,0,-1));
|
|
}
|
|
|
|
void CMainFrame::OnImpulsePosx()
|
|
{
|
|
Apply_Impulse(Vector3(1,0,0));
|
|
}
|
|
|
|
void CMainFrame::OnImpulsePosy()
|
|
{
|
|
Apply_Impulse(Vector3(0,1,0));
|
|
}
|
|
|
|
void CMainFrame::OnImpulsePosz()
|
|
{
|
|
Apply_Impulse(Vector3(0,0,1));
|
|
}
|
|
|
|
void CMainFrame::OnViewImpulsetoolbar()
|
|
{
|
|
ShowControlBar(&m_wndImpulseToolBar,!m_wndImpulseToolBar.IsWindowVisible(),FALSE);
|
|
}
|
|
|
|
void CMainFrame::OnUpdateViewImpulsetoolbar(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(m_wndImpulseToolBar.IsWindowVisible());
|
|
}
|
|
|
|
void CMainFrame::OnViewVirtualjoystick()
|
|
{
|
|
if (VirtualJoystick) {
|
|
if (VirtualJoystick->IsWindowVisible()) {
|
|
VirtualJoystick->ShowWindow(SW_HIDE);
|
|
} else {
|
|
VirtualJoystick->ShowWindow(SW_SHOW);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnUpdateViewVirtualjoystick(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(VirtualJoystick && VirtualJoystick->IsWindowVisible());
|
|
}
|
|
|
|
void CMainFrame::OnInertia()
|
|
{
|
|
RigidBodyClass * rbody = Peek_Selected_RigidBodyClass();
|
|
if (rbody == NULL) return;
|
|
CInertiaDialog dialog(this,rbody);
|
|
dialog.DoModal();
|
|
}
|
|
|
|
void CMainFrame::OnProperties()
|
|
{
|
|
MoveablePhysClass * obj = Peek_Selected_MoveablePhysClass();
|
|
if (obj == NULL) return;
|
|
CRbodyPropertiesDialog dialog(this,obj);
|
|
dialog.DoModal();
|
|
}
|
|
|
|
void CMainFrame::OnUpdateProperties(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(Peek_Selected_MoveablePhysClass() != NULL);
|
|
}
|
|
|
|
void CMainFrame::OnMotorProperties()
|
|
{
|
|
MotorVehicleClass * vehicle = Peek_Selected_MotorVehicleClass();
|
|
if (vehicle == NULL) return;
|
|
CMotorVehicleDialog dialog(this,vehicle);
|
|
dialog.DoModal();
|
|
}
|
|
|
|
void CMainFrame::OnUpdateMotorProperties(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(Peek_Selected_MotorVehicleClass() != NULL);
|
|
}
|
|
|
|
void CMainFrame::OnMotorcycleProperties()
|
|
{
|
|
MotorcycleClass * cycle = Peek_Selected_MotorcycleClass();
|
|
if (cycle == NULL) return;
|
|
CMotorcycleDialog dialog(this,cycle);
|
|
dialog.DoModal();
|
|
}
|
|
|
|
void CMainFrame::OnUpdateMotorcycleProperties(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(Peek_Selected_MotorVehicleClass() != NULL);
|
|
}
|
|
|
|
void CMainFrame::OnWheelProperties()
|
|
{
|
|
WheeledVehicleClass * vehicle = Peek_Selected_WheeledVehicleClass();
|
|
if (vehicle == NULL) return;
|
|
CWheeledVehicleDialog dialog(this,vehicle);
|
|
dialog.DoModal();
|
|
}
|
|
|
|
void CMainFrame::OnUpdateWheelProperties(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(Peek_Selected_WheeledVehicleClass() != NULL);
|
|
}
|
|
|
|
void CMainFrame::OnOptionsPhysicsConstants()
|
|
{
|
|
CPhysicsConstantsDialog dialog;
|
|
dialog.DoModal();
|
|
}
|
|
|
|
void CMainFrame::OnFreezeObject()
|
|
{
|
|
CDataView * data_view = (CDataView *)Splitter.GetPane(0,0);
|
|
CPhysTestDoc * doc = (CPhysTestDoc *)data_view->GetDocument();
|
|
|
|
ItemInfoClass * item = data_view->Get_Selected_Item();
|
|
if (item == NULL) return;
|
|
if (item->Type != ItemInfoClass::INSTANCE) return;
|
|
|
|
RigidBodyClass * rbody = (RigidBodyClass *)item->Instance;
|
|
if (rbody == NULL) return;
|
|
|
|
rbody->Set_Velocity(Vector3(0,0,0));
|
|
rbody->Set_Angular_Velocity(Vector3(0,0,0));
|
|
}
|
|
|
|
void CMainFrame::Set_Status_Bar_Text(const char * text)
|
|
{
|
|
m_wndStatusBar.SetWindowText(text);
|
|
}
|
|
|
|
void CMainFrame::OnDebugObject()
|
|
{
|
|
PhysClass * obj = Peek_Selected_Object();
|
|
obj->Enable_Debug_Display(!obj->Is_Debug_Display_Enabled());
|
|
}
|
|
|
|
void CMainFrame::OnUpdateDebugObject(CCmdUI* pCmdUI)
|
|
{
|
|
PhysClass * obj = Peek_Selected_Object();
|
|
if (obj == NULL) {
|
|
pCmdUI->Enable(FALSE);
|
|
} else {
|
|
pCmdUI->Enable(TRUE);
|
|
pCmdUI->SetCheck(obj->Is_Debug_Display_Enabled());
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnOptionsFilled()
|
|
{
|
|
PhysicsSceneClass::Get_Instance()->Set_Polygon_Mode(SceneClass::FILL);
|
|
}
|
|
|
|
void CMainFrame::OnUpdateOptionsFilled(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(PhysicsSceneClass::Get_Instance()->Get_Polygon_Mode() == SceneClass::FILL);
|
|
}
|
|
|
|
void CMainFrame::OnOptionsPoints()
|
|
{
|
|
PhysicsSceneClass::Get_Instance()->Set_Polygon_Mode(SceneClass::POINT);
|
|
}
|
|
|
|
void CMainFrame::OnUpdateOptionsPoints(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(PhysicsSceneClass::Get_Instance()->Get_Polygon_Mode() == SceneClass::POINT);
|
|
}
|
|
|
|
void CMainFrame::OnOptionsWireframe()
|
|
{
|
|
PhysicsSceneClass::Get_Instance()->Set_Polygon_Mode(SceneClass::LINE);
|
|
}
|
|
|
|
void CMainFrame::OnUpdateOptionsWireframe(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(PhysicsSceneClass::Get_Instance()->Get_Polygon_Mode() == SceneClass::LINE);
|
|
}
|
|
|
|
void CMainFrame::Notify_Selection_Changed(void)
|
|
{
|
|
if (ControlledObject != NULL) {
|
|
ControlledObject->Set_Controller(NULL);
|
|
ControlledObject->Release_Ref();
|
|
ControlledObject = NULL;
|
|
}
|
|
ControlledObject = Peek_Selected_MoveablePhysClass();
|
|
if (ControlledObject) {
|
|
ControlledObject->Add_Ref();
|
|
if (VirtualJoystick) {
|
|
ControlledObject->Set_Controller(&VirtualJoystick->Controller);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnCameraFly()
|
|
{
|
|
CGraphicView * graphic_view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
if (graphic_view) {
|
|
graphic_view->Set_Camera_Mode(CGraphicView::CAMERA_FLY);
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnUpdateCameraFly(CCmdUI* pCmdUI)
|
|
{
|
|
CGraphicView * graphic_view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
if (graphic_view && graphic_view->Get_Camera_Mode() == CGraphicView::CAMERA_FLY) {
|
|
pCmdUI->SetCheck(true);
|
|
} else {
|
|
pCmdUI->SetCheck(false);
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnCameraFollow()
|
|
{
|
|
CGraphicView * graphic_view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
if (graphic_view) {
|
|
graphic_view->Set_Camera_Mode(CGraphicView::CAMERA_FOLLOW);
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnUpdateCameraFollow(CCmdUI* pCmdUI)
|
|
{
|
|
CGraphicView * graphic_view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
if (graphic_view && graphic_view->Get_Camera_Mode() == CGraphicView::CAMERA_FOLLOW) {
|
|
pCmdUI->SetCheck(true);
|
|
} else {
|
|
pCmdUI->SetCheck(false);
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnCameraTether()
|
|
{
|
|
CGraphicView * graphic_view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
if (graphic_view) {
|
|
graphic_view->Set_Camera_Mode(CGraphicView::CAMERA_TETHER);
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnUpdateCameraTether(CCmdUI* pCmdUI)
|
|
{
|
|
CGraphicView * graphic_view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
if (graphic_view && graphic_view->Get_Camera_Mode() == CGraphicView::CAMERA_TETHER) {
|
|
pCmdUI->SetCheck(true);
|
|
} else {
|
|
pCmdUI->SetCheck(false);
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnCameraRigidTether()
|
|
{
|
|
CGraphicView * graphic_view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
if (graphic_view) {
|
|
graphic_view->Set_Camera_Mode(CGraphicView::CAMERA_RIGID_TETHER);
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnUpdateCameraRigidTether(CCmdUI* pCmdUI)
|
|
{
|
|
CGraphicView * graphic_view = (CGraphicView *)Splitter.GetPane(0,1);
|
|
if (graphic_view && graphic_view->Get_Camera_Mode() == CGraphicView::CAMERA_RIGID_TETHER) {
|
|
pCmdUI->SetCheck(true);
|
|
} else {
|
|
pCmdUI->SetCheck(false);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CMainFrame::OnOptionsRenderDevice()
|
|
{
|
|
CRenderDeviceDialog dialog;
|
|
dialog.DoModal();
|
|
}
|
|
|
|
void CMainFrame::OnUpdateOptionsRenderDevice(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->Enable(WW3D::Is_Initted());
|
|
}
|
|
|
|
|
|
void CMainFrame::OnFileImportModel()
|
|
{
|
|
// show the file open dialong
|
|
CFileDialog file_dialog( TRUE, // bOpenFileDialog,
|
|
".W3D", // LPCTSTR lpszDefExt = NULL,
|
|
NULL, // LPCTSTR lpszFileName = NULL,
|
|
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
|
|
"Westwood 3D Files|*.w3d|"
|
|
);
|
|
|
|
// read in the file
|
|
if (file_dialog.DoModal()) {
|
|
Get_Document()->Load_W3D_File(file_dialog.GetPathName());
|
|
}
|
|
}
|
|
|
|
void CMainFrame::OnFileImportLev()
|
|
{
|
|
// show the file open dialong
|
|
CFileDialog file_dialog( TRUE, // bOpenFileDialog,
|
|
".LEV", // LPCTSTR lpszDefExt = NULL,
|
|
NULL, // LPCTSTR lpszFileName = NULL,
|
|
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
|
|
"LEV Files|*.lev|"
|
|
);
|
|
|
|
// read in the file
|
|
if (file_dialog.DoModal()) {
|
|
Get_Document()->Load_LEV_File(file_dialog.GetPathName());
|
|
}
|
|
}
|
|
|