2019-05-15 14:52:37 +00:00
# include "common.h"
2020-04-17 13:31:11 +00:00
2021-01-24 14:06:55 +00:00
# include "main.h"
2020-04-23 20:25:18 +00:00
# include "RwHelper.h"
2019-10-29 23:12:58 +00:00
# include "General.h"
2019-05-15 14:52:37 +00:00
# include "NodeName.h"
# include "VisibilityPlugins.h"
# include "ModelInfo.h"
2020-05-10 09:20:27 +00:00
# include "AnimManager.h"
2021-01-24 14:06:55 +00:00
# include "Streaming.h"
# include "Leeds.h"
base : : cRelocatableChunkClassInfo CClumpModelInfo : : msClassInfo ( " CElementGroupModelInfo " , VTABLE_ADDR ( & msClassInstance ) , sizeof ( msClassInstance ) ) ; // the real name
CClumpModelInfo CClumpModelInfo : : msClassInstance ;
2019-05-15 14:52:37 +00:00
void
CClumpModelInfo : : DeleteRwObject ( void )
{
if ( m_clump ) {
2021-01-24 14:06:55 +00:00
if ( ! gUseChunkFiles )
RpClumpDestroy ( m_clump ) ;
else {
CStreaming : : UnregisterClump ( m_clump ) ;
CStreaming : : UnregisterPointer ( & m_clump , 2 ) ;
DeleteChunk ( ) ;
}
2019-05-15 14:52:37 +00:00
m_clump = nil ;
RemoveTexDictionaryRef ( ) ;
2020-05-10 09:20:27 +00:00
if ( GetAnimFileIndex ( ) ! = - 1 )
CAnimManager : : RemoveAnimBlockRef ( GetAnimFileIndex ( ) ) ;
2019-05-15 14:52:37 +00:00
}
}
2020-04-23 20:25:18 +00:00
static RpAtomic *
SetHierarchyForSkinAtomic ( RpAtomic * atomic , void * data )
{
RpSkinAtomicSetHAnimHierarchy ( atomic , ( RpHAnimHierarchy * ) data ) ;
return nil ;
}
2019-05-15 14:52:37 +00:00
RwObject *
CClumpModelInfo : : CreateInstance ( void )
{
2020-04-23 20:25:18 +00:00
if ( m_clump = = nil )
return nil ;
RpClump * clone = RpClumpClone ( m_clump ) ;
if ( IsClumpSkinned ( clone ) ) {
RpHAnimHierarchy * hier ;
RpHAnimAnimation * anim ;
hier = GetAnimHierarchyFromClump ( clone ) ;
assert ( hier ) ;
RpClumpForAllAtomics ( clone , SetHierarchyForSkinAtomic , hier ) ;
anim = HAnimAnimationCreateForHierarchy ( hier ) ;
RpHAnimHierarchySetCurrentAnim ( hier , anim ) ;
2020-05-10 09:20:27 +00:00
RpHAnimHierarchySetFlags ( hier , ( RpHAnimHierarchyFlag ) ( rpHANIMHIERARCHYUPDATEMODELLINGMATRICES | rpHANIMHIERARCHYUPDATELTMS ) ) ;
2020-04-23 20:25:18 +00:00
}
return ( RwObject * ) clone ;
2019-05-15 14:52:37 +00:00
}
RwObject *
CClumpModelInfo : : CreateInstance ( RwMatrix * m )
{
if ( m_clump ) {
RpClump * clump = ( RpClump * ) CreateInstance ( ) ;
* RwFrameGetMatrix ( RpClumpGetFrame ( clump ) ) = * m ;
2021-01-24 14:06:55 +00:00
CStreaming : : RegisterInstance ( clump ) ;
2019-05-15 14:52:37 +00:00
return ( RwObject * ) clump ;
}
return nil ;
}
RpAtomic *
CClumpModelInfo : : SetAtomicRendererCB ( RpAtomic * atomic , void * data )
{
CVisibilityPlugins : : SetAtomicRenderCallback ( atomic , ( RpAtomicCallBackRender ) data ) ;
return atomic ;
}
void
CClumpModelInfo : : SetClump ( RpClump * clump )
{
m_clump = clump ;
CVisibilityPlugins : : SetClumpModelInfo ( m_clump , this ) ;
AddTexDictionaryRef ( ) ;
2020-05-10 09:20:27 +00:00
if ( GetAnimFileIndex ( ) ! = - 1 )
CAnimManager : : AddAnimBlockRef ( GetAnimFileIndex ( ) ) ;
2020-04-23 20:25:18 +00:00
if ( IsClumpSkinned ( clump ) ) {
2021-01-24 14:06:55 +00:00
//int i;
2020-04-23 20:25:18 +00:00
RpHAnimHierarchy * hier ;
2021-01-24 14:06:55 +00:00
//RpAtomic *skinAtomic;
//RpSkin *skin;
2020-04-23 20:25:18 +00:00
hier = GetAnimHierarchyFromClump ( clump ) ;
assert ( hier ) ;
2020-05-10 09:20:27 +00:00
RpClumpForAllAtomics ( clump , SetHierarchyForSkinAtomic , hier ) ;
2021-01-24 14:06:55 +00:00
/*
2020-05-10 09:20:27 +00:00
skinAtomic = GetFirstAtomic ( clump ) ;
2020-04-23 20:25:18 +00:00
assert ( skinAtomic ) ;
skin = RpSkinGeometryGetSkin ( RpAtomicGetGeometry ( skinAtomic ) ) ;
// ignore const
for ( i = 0 ; i < RpGeometryGetNumVertices ( RpAtomicGetGeometry ( skinAtomic ) ) ; i + + ) {
RwMatrixWeights * weights = ( RwMatrixWeights * ) & RpSkinGetVertexBoneWeights ( skin ) [ i ] ;
float sum = weights - > w0 + weights - > w1 + weights - > w2 + weights - > w3 ;
weights - > w0 / = sum ;
weights - > w1 / = sum ;
weights - > w2 / = sum ;
weights - > w3 / = sum ;
}
2021-01-24 14:06:55 +00:00
*/
2020-05-10 09:20:27 +00:00
RpHAnimHierarchySetFlags ( hier , ( RpHAnimHierarchyFlag ) ( rpHANIMHIERARCHYUPDATEMODELLINGMATRICES | rpHANIMHIERARCHYUPDATELTMS ) ) ;
}
}
void
CClumpModelInfo : : SetAnimFile ( const char * file )
{
if ( strcasecmp ( file , " null " ) = = 0 )
return ;
m_animFileName = new char [ strlen ( file ) + 1 ] ;
strcpy ( m_animFileName , file ) ;
}
void
CClumpModelInfo : : ConvertAnimFileIndex ( void )
{
if ( m_animFileIndex ! = - 1 ) {
// we have a string pointer in that union
int32 index = CAnimManager : : GetAnimationBlockIndex ( m_animFileName ) ;
delete [ ] m_animFileName ;
m_animFileIndex = index ;
2020-04-23 20:25:18 +00:00
}
2019-05-15 14:52:37 +00:00
}
void
CClumpModelInfo : : SetFrameIds ( RwObjectNameIdAssocation * assocs )
{
int32 i ;
RwObjectNameAssociation objname ;
for ( i = 0 ; assocs [ i ] . name ; i + + )
if ( ( assocs [ i ] . flags & CLUMP_FLAG_NO_HIERID ) = = 0 ) {
objname . frame = nil ;
objname . name = assocs [ i ] . name ;
RwFrameForAllChildren ( RpClumpGetFrame ( m_clump ) , FindFrameFromNameWithoutIdCB , & objname ) ;
if ( objname . frame )
CVisibilityPlugins : : SetFrameHierarchyId ( objname . frame , assocs [ i ] . hierId ) ;
}
}
RwFrame *
CClumpModelInfo : : FindFrameFromIdCB ( RwFrame * frame , void * data )
{
RwObjectIdAssociation * assoc = ( RwObjectIdAssociation * ) data ;
2020-05-10 09:20:27 +00:00
if ( CVisibilityPlugins : : GetFrameHierarchyId ( frame ) = = assoc - > id ) {
2019-05-15 14:52:37 +00:00
assoc - > frame = frame ;
return nil ;
}
2020-05-10 09:20:27 +00:00
RwFrameForAllChildren ( frame , FindFrameFromIdCB , assoc ) ;
return assoc - > frame ? nil : frame ;
2019-05-15 14:52:37 +00:00
}
2021-01-22 10:43:29 +00:00
// unused
2019-05-15 14:52:37 +00:00
RwFrame *
CClumpModelInfo : : FindFrameFromNameCB ( RwFrame * frame , void * data )
{
RwObjectNameAssociation * assoc = ( RwObjectNameAssociation * ) data ;
2020-05-10 09:20:27 +00:00
if ( ! CGeneral : : faststricmp ( GetFrameNodeName ( frame ) , assoc - > name ) ) {
2019-05-15 14:52:37 +00:00
assoc - > frame = frame ;
return nil ;
}
2020-05-10 09:20:27 +00:00
RwFrameForAllChildren ( frame , FindFrameFromNameCB , assoc ) ;
return assoc - > frame ? nil : frame ;
2019-05-15 14:52:37 +00:00
}
RwFrame *
CClumpModelInfo : : FindFrameFromNameWithoutIdCB ( RwFrame * frame , void * data )
{
RwObjectNameAssociation * assoc = ( RwObjectNameAssociation * ) data ;
2020-05-10 09:20:27 +00:00
if ( CVisibilityPlugins : : GetFrameHierarchyId ( frame ) = = 0 & &
! CGeneral : : faststricmp ( GetFrameNodeName ( frame ) , assoc - > name ) ) {
2019-05-15 14:52:37 +00:00
assoc - > frame = frame ;
return nil ;
}
2020-05-10 09:20:27 +00:00
RwFrameForAllChildren ( frame , FindFrameFromNameWithoutIdCB , assoc ) ;
return assoc - > frame ? nil : frame ;
2019-05-15 14:52:37 +00:00
}
RwFrame *
CClumpModelInfo : : FillFrameArrayCB ( RwFrame * frame , void * data )
{
int32 id ;
RwFrame * * frames = ( RwFrame * * ) data ;
id = CVisibilityPlugins : : GetFrameHierarchyId ( frame ) ;
if ( id > 0 )
frames [ id ] = frame ;
RwFrameForAllChildren ( frame , FillFrameArrayCB , data ) ;
return frame ;
}
void
CClumpModelInfo : : FillFrameArray ( RpClump * clump , RwFrame * * frames )
{
RwFrameForAllChildren ( RpClumpGetFrame ( clump ) , FillFrameArrayCB , frames ) ;
}
RwFrame *
CClumpModelInfo : : GetFrameFromId ( RpClump * clump , int32 id )
{
RwObjectIdAssociation assoc ;
assoc . id = id ;
assoc . frame = nil ;
RwFrameForAllChildren ( RpClumpGetFrame ( clump ) , FindFrameFromIdCB , & assoc ) ;
return assoc . frame ;
}
2021-01-24 14:06:55 +00:00
void
CClumpModelInfo : : LoadModel ( void * clump , const void * chunk )
{
m_chunk = ( void * ) chunk ;
m_clump = ( RpClump * ) clump ;
LoadResource ( m_clump ) ;
CStreaming : : RegisterPointer ( & m_chunk , 2 , true ) ;
CStreaming : : RegisterClump ( m_clump ) ;
CStreaming : : RegisterPointer ( & m_clump , 2 , true ) ;
}
void
CClumpModelInfo : : Write ( base : : cRelocatableChunkWriter & writer )
{
CBaseModelInfo : : Write ( writer ) ;
if ( m_clump ) {
writer . AddPatch ( & m_clump ) ;
SaveResource ( m_clump , writer ) ;
}
}
void *
CClumpModelInfo : : WriteModel ( base : : cRelocatableChunkWriter & writer )
{
if ( m_clump )
SaveResource ( m_clump , writer ) ;
return m_clump ;
}
void
CClumpModelInfo : : RcWriteThis ( base : : cRelocatableChunkWriter & writer )
{
writer . AllocateRaw ( this , sizeof ( * this ) , sizeof ( void * ) , false , true ) ;
writer . Class ( VTABLE_ADDR ( this ) , msClassInfo ) ;
}
void
CClumpModelInfo : : RcWriteEmpty ( base : : cRelocatableChunkWriter & writer )
{
writer . AllocateRaw ( this , sizeof ( * this ) , sizeof ( void * ) , false , true ) ;
writer . Class ( VTABLE_ADDR ( this ) , msClassInfo ) ;
}