This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/Tools/W3DView/AdvancedAnimSheet.cpp

197 lines
4.8 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/>.
*/
// AdvancedAnimSheet.cpp : implementation file
//
#include "stdafx.h"
#include "w3dview.h"
#include "W3dViewDoc.h"
#include "AdvancedAnimSheet.h"
#include "AssetMgr.h"
#include "HAnim.h"
#include "HTree.h"
#include "Utils.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// QSort comparison function for HAnimClass pointers.
// Will compare their names.
static int anim_name_compare (const void *arg1, const void *arg2)
{
ASSERT(arg1 != NULL);
ASSERT(arg2 != NULL);
HAnimClass *a1 = *(HAnimClass**)arg1;
HAnimClass *a2 = *(HAnimClass**)arg2;
return _stricmp( a1->Get_Name(), a2->Get_Name() );
}
/////////////////////////////////////////////////////////////////////////////
// CAdvancedAnimSheet
IMPLEMENT_DYNAMIC(CAdvancedAnimSheet, CPropertySheet)
CAdvancedAnimSheet::CAdvancedAnimSheet(CWnd* pParentWnd, UINT iSelectPage)
: CPropertySheet("Advanced Animation", pParentWnd, iSelectPage),
m_MixingPage(this),
m_ReportPage(this),
AnimsValid(false),
AnimCount(0)
{
// Blank out the array of animation pointers.
ZeroMemory(Anims, sizeof(Anims));
// Add the property pages into this property sheet.
AddPage(&m_MixingPage);
AddPage(&m_ReportPage);
}
CAdvancedAnimSheet::~CAdvancedAnimSheet()
{
if (AnimsValid)
{
for (int i = 0; i < AnimCount; i++)
{
MEMBER_RELEASE(Anims[i]);
}
AnimsValid = false;
AnimCount = 0;
}
}
BEGIN_MESSAGE_MAP(CAdvancedAnimSheet, CPropertySheet)
//{{AFX_MSG_MAP(CAdvancedAnimSheet)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAdvancedAnimSheet message handlers
int CAdvancedAnimSheet::GetAnimCount (void)
{
if (AnimsValid)
return AnimCount;
LoadAnims();
if (AnimsValid)
return AnimCount;
else
return 0;
}
HAnimClass ** CAdvancedAnimSheet::GetAnims (void)
{
if (AnimsValid)
return Anims;
LoadAnims();
// Return the array regardless of validity. If the entries are
// invalid, they'll all be NULL, but the array itself is cool.
return Anims;
}
void CAdvancedAnimSheet::LoadAnims (void)
{
// Get the current render object and it's HTree. If it doesn't have
// an HTree, then it's not animating and we're not interested.
RenderObjClass *robj = ::GetCurrentDocument()->GetDisplayedObject();
if (robj == NULL)
return;
const HTreeClass *htree = robj->Get_HTree();
if (htree == NULL)
return;
const char *htree_name = htree->Get_Name();
/*
** Figure out which animations apply to the current object, and
** add each one to the array of animations which we will later sort.
*/
// Get an iterator from the asset manager that we can
// use to enumerate the currently loaded assets
AssetIterator *pAnimEnum = WW3DAssetManager::Get_Instance()->Create_HAnim_Iterator();
ASSERT(pAnimEnum != NULL);
if (pAnimEnum)
{
// Loop through all the animations in the manager
for (pAnimEnum->First(); pAnimEnum->Is_Done() == FALSE; pAnimEnum->Next())
{
LPCTSTR pszAnimName = pAnimEnum->Current_Item_Name();
// Get an instance of the animation object
HAnimClass *pHierarchyAnim = WW3DAssetManager::Get_Instance()->Get_HAnim(pszAnimName);
ASSERT(pHierarchyAnim != NULL);
if (pHierarchyAnim)
{
// Does this animation apply to the current model's HTree?
if (stricmp(htree_name, pHierarchyAnim->Get_HName()) == 0)
{
// Add this Anims pointer to the array.
if (AnimCount < MAX_REPORT_ANIMS)
{
MEMBER_ADD(Anims[AnimCount], pHierarchyAnim);
AnimCount++;
}
else
{
char msg[256];
sprintf(msg, "Error: Only %d animations are supported in this report. "
" There are more than that loaded...", MAX_REPORT_ANIMS);
MessageBox(msg, "Too Many Animations");
break;
}
}
// Release our hold on this animation.
MEMBER_RELEASE(pHierarchyAnim);
}
}
// Free the object
delete pAnimEnum;
pAnimEnum = NULL;
}
/*
** Sort the array of animations in alphabetical order.
*/
qsort(Anims, AnimCount, sizeof(HAnimClass*), anim_name_compare);
AnimsValid = true;
}