/* ** 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 . */ // PhysTestDoc.cpp : implementation of the CPhysTestDoc class // #include "stdafx.h" #include "PhysTest.h" #include "PhysTestDoc.h" #include "MainFrm.h" #include "DataView.h" #include "ww3d.h" #include "ffactory.h" #include "pscene.h" #include "light.h" #include "rcfile.h" #include "assetmgr.h" #include "rendobj.h" #include "chunkio.h" #include "lev_file.h" #include "physlist.h" #include "saveload.h" #include "chunkio.h" #include "rawfile.h" #include "physstaticsavesystem.h" #include "physdynamicsavesystem.h" #include "PhysTestSaveSystem.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // Chunk ID's used by PhysTestDoc enum { PHYSTESTDOC_CHUNK_MAINFRAME = 0x03321990, PHYSTESTDOC_CHUNK_SYSTEMS, }; ///////////////////////////////////////////////////////////////////////////// // CPhysTestDoc IMPLEMENT_DYNCREATE(CPhysTestDoc, CDocument) BEGIN_MESSAGE_MAP(CPhysTestDoc, CDocument) //{{AFX_MSG_MAP(CPhysTestDoc) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPhysTestDoc construction/destruction CPhysTestDoc::CPhysTestDoc() : Scene(NULL), Light(NULL), Origin(NULL) { } CPhysTestDoc::~CPhysTestDoc() { if (Scene) { Scene->Remove_All(); } REF_PTR_RELEASE(Scene); REF_PTR_RELEASE(Light); REF_PTR_RELEASE(Origin); } void CPhysTestDoc::Init_Scene(void) { if (Scene == NULL) { // Instantiate a new scene Scene = NEW_REF(PhysicsSceneClass,()); Scene->Enable_Dynamic_Projectors(true); // Were we successful in instantiating the scene object? ASSERT(Scene); if (Scene != NULL) { // Set up some collision groups. Scene->Enable_All_Collision_Detections(0); // Set some default ambient lighting Scene->Set_Ambient_Light(Vector3 (0.5F, 0.5F, 0.5F)); // Create a new scene light if (Light == NULL) { Light = NEW_REF(LightClass,(LightClass::DIRECTIONAL)); ASSERT(Light); if (Light) { // Create some default light settings Matrix3D transform(1); transform.Look_At(Vector3(0,0,0),Vector3(10,10,10),0.0f); Light->Set_Transform(transform); Light->Set_Attenuation_Model(LightClass::ATTENUATION_NONE); Light->Set_Flag (LightClass::NEAR_ATTENUATION, false); Light->Set_Flag (LightClass::FAR_ATTENUATION, false); Light->Set_Far_Attenuation_Range (1000000, 1000000); Light->Set_Intensity(1.0F); Light->Set_Force_Visible(true); Light->Set_Ambient(Vector3(0,0,0)); Light->Set_Diffuse(Vector3(1, 1, 1)); Light->Set_Specular(Vector3(1, 1, 1)); // Add this light to the scene Light->Add(Scene); } } // Create an object at the Origin if (Origin == NULL) { ResourceFileClass mesh_file(NULL, "Axes.w3d"); WW3DAssetManager::Get_Instance()->Load_3D_Assets(mesh_file); Origin = WW3DAssetManager::Get_Instance()->Create_Render_Obj("Axes"); Origin->Set_Transform(Matrix3D(1)); Scene->Add_Render_Object(Origin); } } } } ///////////////////////////////////////////////////////////////////////////// // CPhysTestDoc serialization void CPhysTestDoc::Serialize(CArchive& ar) { assert(0); } ///////////////////////////////////////////////////////////////////////////// // CPhysTestDoc diagnostics #ifdef _DEBUG void CPhysTestDoc::AssertValid() const { CDocument::AssertValid(); } void CPhysTestDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CPhysTestDoc commands BOOL CPhysTestDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; if (Scene) { Scene->Remove_All(); WWASSERT(Light); if (Light) { Scene->Add_Render_Object(Light); } WWASSERT(Origin); if (Origin) { Scene->Add_Render_Object(Origin); } // rebuild the list view Get_Data_View()->Rebuild_Tree(); } return TRUE; } BOOL CPhysTestDoc::OnOpenDocument(LPCTSTR lpszPathName) { Load_PHY_File(lpszPathName); Get_Data_View()->Rebuild_Tree(); return TRUE; } BOOL CPhysTestDoc::OnSaveDocument(LPCTSTR lpszPathName) { Save_PHY_File(lpszPathName); return TRUE; } /////////////////////////////////////////////////////////////// // // Load_LEV_File // void CPhysTestDoc::Load_LEV_File(LPCTSTR lpszPathName) { #if 0 WWASSERT(Scene); // // HACK HACK -- Force the current directory to be the directory // the file is located in. // if (::strrchr (lpszPathName, '\\')) { CString stringTemp = lpszPathName; stringTemp = stringTemp.Left ((long)::strrchr (lpszPathName, '\\') - (long)lpszPathName); ::SetCurrentDirectory (stringTemp); WW3D::Add_Search_Path (stringTemp); } LPCTSTR extension = ::strrchr (lpszPathName, '.'); ASSERT(::lstrcmpi(extension,".lev") == 0); // load the LEV FileClass *file = DefaultFileFactory.Get_File (lpszPathName); file->Open(); ChunkLoadClass cload(file); // should see a LEV_CHUNK_LEVEL cload.Open_Chunk(); WWASSERT(cload.Cur_Chunk_ID() == LEV_CHUNK_LEVEL); // for now only look for a LEV_CHUNK_MAP cload.Open_Chunk(); WWASSERT(cload.Cur_Chunk_ID() == LEV_CHUNK_MAP); // Physics Scene handles the tile map loading Scene->LEV_Load(cload); // close the LEV_CHUNK_MAP cload.Close_Chunk(); // close the LEV_CHUNK_LEVEL cload.Close_Chunk(); // done with the file! file->Close(); DefaultFileFactory.Return_File(file); // Replace our default objects WWASSERT(Light); if (Light) { Scene->Add_Render_Object(Light); } WWASSERT(Origin); if (Origin) { Scene->Add_Render_Object(Origin); } #endif } /////////////////////////////////////////////////////////////// // // Load_W3D_File // void CPhysTestDoc::Load_W3D_File(LPCTSTR lpszPathName) { WW3DAssetManager::Get_Instance()->Load_3D_Assets(lpszPathName); // rebuild the list view Get_Data_View()->Rebuild_Tree(); } /////////////////////////////////////////////////////////////// // // Load_PHY_File // void CPhysTestDoc::Load_PHY_File(LPCTSTR lpszPathName) { RawFileClass file(lpszPathName); WWASSERT(file); file.Open(FileClass::READ); ChunkLoadClass cload(&file); while (cload.Open_Chunk()) { switch(cload.Cur_Chunk_ID()) { case PHYSTESTDOC_CHUNK_SYSTEMS: SaveLoadSystemClass::Load( cload ); break; }; cload.Close_Chunk(); } file.Close(); } /////////////////////////////////////////////////////////////// // // Save_PHY_File // void CPhysTestDoc::Save_PHY_File(LPCTSTR lpszPathName) { RawFileClass file(lpszPathName); WWASSERT(file); file.Open(FileClass::WRITE); ChunkSaveClass csave(&file); csave.Begin_Chunk(PHYSTESTDOC_CHUNK_SYSTEMS); SaveLoadSystemClass::Save( csave, _PhysTestSaveSystem ); SaveLoadSystemClass::Save( csave, _PhysStaticDataSaveSystem ); SaveLoadSystemClass::Save( csave, _PhysStaticObjectsSaveSystem ); SaveLoadSystemClass::Save( csave, _PhysDynamicSaveSystem ); csave.End_Chunk(); file.Close(); } /////////////////////////////////////////////////////////////// // // Get_Data_View // CDataView * CPhysTestDoc::Get_Data_View(void) { CDataView * view = NULL; // Get a pointer to the main window CMainFrame * mainwnd = (CMainFrame *)::AfxGetMainWnd(); if (mainwnd) { // Get the pane from the main window view = (CDataView *)mainwnd->Get_Pane(0,0); } // Return a pointer to the tree view return view; } /////////////////////////////////////////////////////////////// // // Get_Graphic_View // CGraphicView * CPhysTestDoc::Get_Graphic_View(void) { CGraphicView * view = NULL; // Get a pointer to the main window CMainFrame * mainwnd = (CMainFrame *)::AfxGetMainWnd(); if (mainwnd) { // Get the pane from the main window view = (CGraphicView *)mainwnd->Get_Pane(0,1); } // Return a pointer to the graphic view return view; } /////////////////////////////////////////////////////////////// // // Add_Physics_Object - add a new object to be simulated // void CPhysTestDoc::Add_Physics_Object(PhysClass * obj) { if (obj == NULL) return; if (Scene == NULL) return; Scene->Add_Dynamic_Object(obj); // rebuild the list view Get_Data_View()->Rebuild_Tree(); } int CPhysTestDoc::Get_Physics_Object_Count(void) { PhysListIterator it = Scene->Get_Dynamic_Object_Iterator(); int count = 0; for (it.First(); !it.Is_Done(); it.Next()) { count++; } return count; }