mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-29 06:07:57 +03:00
566 lines
18 KiB
C++
566 lines
18 KiB
C++
/*
|
|
===========================================================================
|
|
Copyright (C) 2015 the OpenMoHAA team
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
OpenMoHAA source code 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 2 of the License,
|
|
or (at your option) any later version.
|
|
|
|
OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
===========================================================================
|
|
*/
|
|
|
|
// skeletor_loadanimation.cpp : Responsible of loading animations
|
|
|
|
#include "q_shared.h"
|
|
#include "qcommon.h"
|
|
#include "skeletor.h"
|
|
|
|
qboolean Compress( skelAnimGameFrame_t *current, skelAnimGameFrame_t *last, int channelIndex, skelChannelList_c *channelList, ChannelNameTable *channelNames )
|
|
{
|
|
float tolerance;
|
|
float difference;
|
|
|
|
// high-end PC don't need to compress...
|
|
return false;
|
|
|
|
tolerance = current->pChannels[ channelIndex ][ 0 ];
|
|
if( tolerance > -0.000001 && tolerance < 0.000001 )
|
|
{
|
|
current->pChannels[ channelIndex ][ 0 ] = 0.0f;
|
|
}
|
|
|
|
tolerance = current->pChannels[ channelIndex ][ 1 ];
|
|
if( tolerance > -0.000001 && tolerance < 0.000001 )
|
|
{
|
|
current->pChannels[ channelIndex ][ 1 ] = 0.0f;
|
|
}
|
|
|
|
tolerance = current->pChannels[ channelIndex ][ 2 ];
|
|
if( tolerance > -0.000001 && tolerance < 0.000001 )
|
|
{
|
|
current->pChannels[ channelIndex ][ 2 ] = 0.0f;
|
|
}
|
|
|
|
if( !last )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
difference = last->pChannels[ channelIndex ][ 0 ] - current->pChannels[ channelIndex ][ 0 ];
|
|
if( difference < -0.001f || difference >= 0.001f )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
difference = last->pChannels[ channelIndex ][ 1 ] - current->pChannels[ channelIndex ][ 1 ];
|
|
if( difference < -0.001f || difference >= 0.001f )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
difference = last->pChannels[ channelIndex ][ 2 ] - current->pChannels[ channelIndex ][ 2 ];
|
|
if( difference < -0.001f || difference >= 0.001f )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
skelAnimDataGameHeader_t *EncodeFrames( skelAnimDataGameHeader_t *enAnim, skelAnimGameFrame_t *m_frame, qboolean bLog, skelChannelList_c *channelList, ChannelNameTable *channelNames )
|
|
{
|
|
int endFrameCap;
|
|
skanChannelHdr *pChannel;
|
|
int i, j;
|
|
int frameCnt;
|
|
skelAnimGameFrame_t *pCurrFrame;
|
|
skelAnimGameFrame_t *pLastFrame;
|
|
skanGameFrame *pFrame;
|
|
int indexLastFrameAdded;
|
|
|
|
pChannel = enAnim->ary_channels;
|
|
endFrameCap = enAnim->numFrames - 2;
|
|
|
|
for( i = 0; i < enAnim->nTotalChannels; i++, pChannel++ )
|
|
{
|
|
pLastFrame = NULL;
|
|
pCurrFrame = m_frame;
|
|
|
|
frameCnt = 0;
|
|
for( j = 0; j < enAnim->numFrames; j++ )
|
|
{
|
|
if( !Compress( pCurrFrame, pLastFrame, i, channelList, channelNames ) || j >= endFrameCap )
|
|
{
|
|
frameCnt++;
|
|
pLastFrame = pCurrFrame;
|
|
}
|
|
|
|
pCurrFrame++;
|
|
}
|
|
|
|
pChannel->ary_frames = ( skanGameFrame * )Skel_Alloc( frameCnt * sizeof( skanGameFrame ) );
|
|
pChannel->nFramesInChannel = frameCnt;
|
|
enAnim->nBytesUsed += frameCnt * sizeof( skanGameFrame );
|
|
|
|
pLastFrame = NULL;
|
|
indexLastFrameAdded = 0;
|
|
|
|
pCurrFrame = m_frame;
|
|
pFrame = pChannel->ary_frames;
|
|
|
|
for( j = 0; j < enAnim->numFrames; j++ )
|
|
{
|
|
if( !Compress( pCurrFrame, pLastFrame, i, channelList, channelNames ) || j >= endFrameCap )
|
|
{
|
|
pFrame->nFrameNum = j;
|
|
pFrame->nPrevFrameIndex = indexLastFrameAdded;
|
|
|
|
if( j > 0 )
|
|
indexLastFrameAdded++;
|
|
|
|
pFrame->pChannelData[ 0 ] = pCurrFrame->pChannels[ i ][ 0 ];
|
|
pFrame->pChannelData[ 1 ] = pCurrFrame->pChannels[ i ][ 1 ];
|
|
pFrame->pChannelData[ 2 ] = pCurrFrame->pChannels[ i ][ 2 ];
|
|
pFrame->pChannelData[ 3 ] = pCurrFrame->pChannels[ i ][ 3 ];
|
|
pFrame++;
|
|
|
|
pLastFrame = pCurrFrame;
|
|
}
|
|
|
|
pCurrFrame++;
|
|
}
|
|
}
|
|
|
|
return enAnim;
|
|
}
|
|
|
|
skelAnimDataGameHeader_t *skeletor_c::ConvertSkelFileToGame( skelAnimDataFileHeader_t *pHeader, int iBuffLength, const char *path )
|
|
{
|
|
int i;
|
|
skelAnimFileFrame_t *pFileFrame;
|
|
skelAnimGameFrame_t *pGameFrame;
|
|
skelChannelName_t *pChannelNames;
|
|
skelAnimDataGameHeader_t *enAnim;
|
|
skelAnimGameFrame_t *oldFrame;
|
|
skelAnimGameFrame_t *newFrame;
|
|
int channelIndex;
|
|
|
|
if( pHeader->numFrames <= 0 )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pGameFrame = new skelAnimGameFrame_t[ pHeader->numFrames ];
|
|
pFileFrame = pHeader->frame;
|
|
newFrame = pGameFrame;
|
|
|
|
for( i = 0; i < pHeader->numFrames; i++ )
|
|
{
|
|
newFrame->bounds[ 0 ] = pFileFrame->bounds[ 0 ];
|
|
newFrame->bounds[ 1 ] = pFileFrame->bounds[ 1 ];
|
|
newFrame->delta = pFileFrame->delta;
|
|
newFrame->angleDelta = pFileFrame->angleDelta;
|
|
newFrame->pChannels = new vec4_t[ pHeader->numChannels ];
|
|
memcpy( newFrame->pChannels,
|
|
( char * )pHeader + ( sizeof( vec4_t ) * ( 3 * pHeader->numFrames - 3 ) + sizeof( vec4_t ) * pHeader->numChannels * i + 96 ),
|
|
pHeader->numChannels * sizeof( vec4_t ) );
|
|
AddToBounds( newFrame->bounds, pFileFrame->bounds );
|
|
|
|
pFileFrame++;
|
|
newFrame++;
|
|
}
|
|
|
|
enAnim = skelAnimDataGameHeader_t::AllocRLEChannelData( pHeader->numChannels );
|
|
enAnim->flags = pHeader->flags;
|
|
enAnim->frameTime = pHeader->frameTime;
|
|
enAnim->totalDelta = pHeader->totalDelta;
|
|
enAnim->totalAngleDelta = pHeader->totalAngleDelta;
|
|
enAnim->numFrames = pHeader->numFrames;
|
|
enAnim->nTotalChannels = pHeader->numChannels;
|
|
ClearBounds( enAnim->bounds[ 0 ], enAnim->bounds[ 1 ] );
|
|
enAnim->m_frame = ( skelAnimGameFrame_t * )Skel_Alloc( pHeader->numFrames * sizeof( skelAnimGameFrame_t ) );
|
|
|
|
oldFrame = pGameFrame;
|
|
newFrame = enAnim->m_frame;
|
|
|
|
for( i = 0; i < pHeader->numFrames; i++ )
|
|
{
|
|
newFrame->bounds[ 0 ] = oldFrame->bounds[ 0 ];
|
|
newFrame->bounds[ 1 ] = oldFrame->bounds[ 1 ];
|
|
newFrame->radius = oldFrame->radius;
|
|
newFrame->delta = oldFrame->delta;
|
|
newFrame->angleDelta = oldFrame->angleDelta;
|
|
newFrame->pChannels = NULL;
|
|
AddToBounds( enAnim->bounds, oldFrame->bounds );
|
|
|
|
oldFrame++;
|
|
newFrame++;
|
|
}
|
|
|
|
enAnim->channelList.ZeroChannels();
|
|
|
|
pChannelNames = ( skelChannelName_t * )( ( char * )pHeader + pHeader->ofsChannelNames );
|
|
|
|
for( i = 0; i < pHeader->numChannels; i++ )
|
|
{
|
|
channelIndex = m_channelNames.RegisterChannel( *pChannelNames );
|
|
enAnim->channelList.AddChannel( channelIndex );
|
|
pChannelNames++;
|
|
}
|
|
|
|
enAnim->channelList.PackChannels();
|
|
EncodeFrames( enAnim, pGameFrame, qfalse, &enAnim->channelList, &m_channelNames );
|
|
|
|
if( enAnim->channelList.HasChannel( &m_channelNames, "Bip01 pos" ) &&
|
|
enAnim->channelList.HasChannel( &m_channelNames, "Bip01 R Foot pos" ) &&
|
|
enAnim->channelList.HasChannel( &m_channelNames, "Bip01 L Foot pos" ) )
|
|
{
|
|
enAnim->bHasDelta = true;
|
|
}
|
|
else
|
|
{
|
|
enAnim->bHasDelta = false;
|
|
}
|
|
|
|
if( enAnim->channelList.HasChannel( &m_channelNames, "Bip01 Spine rot" ) &&
|
|
enAnim->channelList.HasChannel( &m_channelNames, "Bip01 Spine1 rot" ) )
|
|
{
|
|
enAnim->bHasUpper = true;
|
|
}
|
|
else
|
|
{
|
|
enAnim->bHasUpper = false;
|
|
}
|
|
|
|
if( enAnim->channelList.HasChannel( &m_channelNames, "VISEME_Bump" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "VISME_Cage_" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "VISME_Earth" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "VISME_Fave" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "VISME_If" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "VISME_New" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "VISME_Ox" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "VISME_Roar" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "VISME_Size" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "VISME_Though" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "VISME_Told" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "VISME_Wet" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "BROW_frown" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "BROW_R_lift" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "BROW_lift" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "BROW_worry" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "EYE_blink" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "EYES_Excited__" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "EYES_L_squint" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "EYES_narrow__" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "EYES_down" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "EYES_left" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "EYES_right" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "EYES_smile" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "EYES_up__" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "JAW_open-closed" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "JAW_open-open" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "LIPS_compressed" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "MOUTH_L_smile_closed" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "MOUTH_L_smile_open" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "MOUTH_L_snarl_closed_" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "MOUTH_L_snarl_open" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "MOUTH_grimace" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "MOUTH_smile_closed" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "MOUTH_smile_open" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "MOUTH_Snarl_closed" )
|
|
|| enAnim->channelList.HasChannel( &m_channelNames, "MOUTH_Snarl_open" ) )
|
|
{
|
|
enAnim->bHasMorph = true;
|
|
}
|
|
else
|
|
{
|
|
enAnim->bHasMorph = false;
|
|
}
|
|
|
|
for( i = 0; i < pHeader->numFrames; i++ )
|
|
{
|
|
if( pGameFrame[ i ].pChannels )
|
|
delete[] pGameFrame[ i ].pChannels;
|
|
}
|
|
|
|
delete[] pGameFrame;
|
|
return enAnim;
|
|
}
|
|
|
|
void WriteEncodedFrames( msg_t *msg, skelAnimDataGameHeader_t *enAnim )
|
|
{
|
|
skanChannelHdr *pChannel;
|
|
skanGameFrame *pFrame;
|
|
int i, j;
|
|
|
|
MSG_WriteLong( msg, enAnim->numFrames );
|
|
MSG_WriteShort( msg, enAnim->nTotalChannels );
|
|
|
|
for( i = 0; i < enAnim->nTotalChannels; i++ )
|
|
{
|
|
pChannel = &enAnim->ary_channels[ i ];
|
|
MSG_WriteShort( msg, pChannel->nFramesInChannel );
|
|
|
|
for( j = 0; j < pChannel->nFramesInChannel; j++ )
|
|
{
|
|
pFrame = &pChannel->ary_frames[ i ];
|
|
MSG_WriteShort( msg, pFrame->nFrameNum );
|
|
MSG_WriteShort( msg, pFrame->nPrevFrameIndex );
|
|
MSG_WriteData( msg, pFrame->pChannelData, sizeof( vec4_t ) );
|
|
}
|
|
}
|
|
|
|
MSG_WriteLong( msg, enAnim->nBytesUsed );
|
|
}
|
|
|
|
void skeletor_c::SaveProcessedAnim( skelAnimDataGameHeader_t *enAnim, const char *path, skelAnimDataFileHeader_t *pHeader )
|
|
{
|
|
/*
|
|
int i;
|
|
skelChannelName_t *pChannelNames;
|
|
msg_t msg;
|
|
skelAnimGameFrame_t *newFrame;
|
|
char npath[ 128 ];
|
|
unsigned char buf[ 2000000 ];
|
|
|
|
// FIXME:
|
|
// Write animation
|
|
*/
|
|
}
|
|
|
|
void ReadEncodedFrames( msg_t *msg, skelAnimDataGameHeader_t *enAnim )
|
|
{
|
|
skanChannelHdr *pChannel;
|
|
skanGameFrame *pFrame;
|
|
int frameCnt;
|
|
int i, j;
|
|
|
|
enAnim->numFrames = MSG_ReadLong( msg );
|
|
enAnim->nTotalChannels = MSG_ReadShort( msg );
|
|
|
|
for( i = 0; i < enAnim->nTotalChannels; i++ )
|
|
{
|
|
pChannel = &enAnim->ary_channels[ i ];
|
|
frameCnt = MSG_ReadShort( msg );
|
|
|
|
pFrame = ( skanGameFrame * )Skel_Alloc( frameCnt * sizeof( skanGameFrame ) );
|
|
pChannel->ary_frames = pFrame;
|
|
pChannel->nFramesInChannel = frameCnt;
|
|
|
|
for( j = 0; j < pChannel->nFramesInChannel; j++ )
|
|
{
|
|
pFrame = &pChannel->ary_frames[ j ];
|
|
pFrame->nFrameNum = MSG_ReadShort( msg );
|
|
pFrame->nPrevFrameIndex = MSG_ReadShort( msg );
|
|
MSG_ReadData( msg, pFrame->pChannelData, sizeof( vec4_t ) );
|
|
}
|
|
}
|
|
|
|
enAnim->nBytesUsed = MSG_ReadLong( msg );
|
|
}
|
|
|
|
void ReadEncodedFramesEx( msg_t *msg, skelAnimDataGameHeader_t *enAnim )
|
|
{
|
|
skanChannelHdr *pChannel;
|
|
skanGameFrame *pFrame;
|
|
int frameCnt;
|
|
int i, j;
|
|
const char *name;
|
|
int type;
|
|
|
|
for( i = 0; i < enAnim->nTotalChannels; i++ )
|
|
{
|
|
pChannel = &enAnim->ary_channels[ i ];
|
|
|
|
name = enAnim->channelList.ChannelName( &skeletor_c::m_channelNames, i );
|
|
type = GetChannelTypeFromName( name );
|
|
frameCnt = MSG_ReadShort( msg );
|
|
|
|
pFrame = ( skanGameFrame * )Skel_Alloc( frameCnt * sizeof( skanGameFrame ) );
|
|
pChannel->ary_frames = pFrame;
|
|
pChannel->nFramesInChannel = frameCnt;
|
|
|
|
if( type )
|
|
{
|
|
if( type == 1 )
|
|
{
|
|
for( j = 0; j < pChannel->nFramesInChannel; j++ )
|
|
{
|
|
pFrame = &pChannel->ary_frames[ j ];
|
|
pFrame->nFrameNum = MSG_ReadShort( msg );
|
|
pFrame->nPrevFrameIndex = MSG_ReadShort( msg );
|
|
pFrame->pChannelData[ 0 ] = MSG_ReadFloat( msg );
|
|
pFrame->pChannelData[ 1 ] = MSG_ReadFloat( msg );
|
|
pFrame->pChannelData[ 2 ] = MSG_ReadFloat( msg );
|
|
pFrame->pChannelData[ 3 ] = 0;
|
|
}
|
|
}
|
|
else if( type == 3 )
|
|
{
|
|
for( j = 0; j < pChannel->nFramesInChannel; j++ )
|
|
{
|
|
pFrame = &pChannel->ary_frames[ j ];
|
|
pFrame->nFrameNum = MSG_ReadShort( msg );
|
|
pFrame->nPrevFrameIndex = MSG_ReadShort( msg );
|
|
pFrame->pChannelData[ 0 ] = MSG_ReadFloat( msg );
|
|
pFrame->pChannelData[ 1 ] = 0;
|
|
pFrame->pChannelData[ 2 ] = 0;
|
|
pFrame->pChannelData[ 3 ] = 0;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( j = 0; j < pChannel->nFramesInChannel; j++ )
|
|
{
|
|
pFrame = &pChannel->ary_frames[ j ];
|
|
pFrame->nFrameNum = MSG_ReadShort( msg );
|
|
pFrame->nPrevFrameIndex = MSG_ReadShort( msg );
|
|
pFrame->pChannelData[ 0 ] = MSG_ReadFloat( msg );
|
|
pFrame->pChannelData[ 1 ] = MSG_ReadFloat( msg );
|
|
pFrame->pChannelData[ 2 ] = MSG_ReadFloat( msg );
|
|
pFrame->pChannelData[ 3 ] = MSG_ReadFloat( msg );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
skelAnimDataGameHeader_t *skeletor_c::LoadProcessedAnim( const char *path, void *buffer, int len, const char *name )
|
|
{
|
|
skelAnimDataGameHeader_t *enAnim;
|
|
int i;
|
|
msg_t msg;
|
|
int numChannels;
|
|
skelAnimGameFrame_t *newFrame;
|
|
|
|
MSG_Init( &msg, ( byte * )buffer, len );
|
|
msg.cursize = len;
|
|
MSG_BeginReading( &msg );
|
|
|
|
numChannels = MSG_ReadLong( &msg );
|
|
enAnim = skelAnimDataGameHeader_t::AllocRLEChannelData( numChannels );
|
|
enAnim->flags = MSG_ReadLong( &msg );
|
|
enAnim->frameTime = MSG_ReadFloat( &msg );
|
|
enAnim->totalDelta[ 0 ] = MSG_ReadFloat( &msg );
|
|
enAnim->totalDelta[ 1 ] = MSG_ReadFloat( &msg );
|
|
enAnim->totalDelta[ 2 ] = MSG_ReadFloat( &msg );
|
|
enAnim->totalAngleDelta = MSG_ReadFloat( &msg );
|
|
enAnim->numFrames = MSG_ReadLong( &msg );
|
|
enAnim->nTotalChannels = MSG_ReadShort( &msg );
|
|
enAnim->bHasDelta = MSG_ReadByte( &msg ) != 0;
|
|
enAnim->bHasUpper = MSG_ReadByte( &msg ) != 0;
|
|
enAnim->bHasMorph = MSG_ReadByte( &msg ) != 0;
|
|
|
|
newFrame = ( skelAnimGameFrame_t * )Skel_Alloc( enAnim->numFrames * sizeof( skelAnimGameFrame_t ) );
|
|
enAnim->m_frame = newFrame;
|
|
|
|
for( i = 0; i < enAnim->numFrames; i++ )
|
|
{
|
|
newFrame->bounds[ 0 ][ 0 ] = MSG_ReadFloat( &msg );
|
|
newFrame->bounds[ 0 ][ 1 ] = MSG_ReadFloat( &msg );
|
|
newFrame->bounds[ 0 ][ 2 ] = MSG_ReadFloat( &msg );
|
|
newFrame->bounds[ 1 ][ 0 ] = MSG_ReadFloat( &msg );
|
|
newFrame->bounds[ 1 ][ 1 ] = MSG_ReadFloat( &msg );
|
|
newFrame->bounds[ 1 ][ 2 ] = MSG_ReadFloat( &msg );
|
|
newFrame->radius = MSG_ReadFloat( &msg );
|
|
newFrame->delta[ 0 ] = MSG_ReadFloat( &msg );
|
|
newFrame->delta[ 1 ] = MSG_ReadFloat( &msg );
|
|
newFrame->delta[ 2 ] = MSG_ReadFloat( &msg );
|
|
newFrame->angleDelta = MSG_ReadFloat( &msg );
|
|
newFrame->pChannels = NULL;
|
|
newFrame++;
|
|
}
|
|
|
|
enAnim->bounds[ 0 ][ 0 ] = MSG_ReadFloat( &msg );
|
|
enAnim->bounds[ 0 ][ 1 ] = MSG_ReadFloat( &msg );
|
|
enAnim->bounds[ 0 ][ 2 ] = MSG_ReadFloat( &msg );
|
|
enAnim->bounds[ 1 ][ 0 ] = MSG_ReadFloat( &msg );
|
|
enAnim->bounds[ 1 ][ 1 ] = MSG_ReadFloat( &msg );
|
|
enAnim->bounds[ 1 ][ 2 ] = MSG_ReadFloat( &msg );
|
|
ReadEncodedFrames( &msg, enAnim );
|
|
numChannels = MSG_ReadLong( &msg );
|
|
enAnim->channelList.ZeroChannels();
|
|
|
|
for( i = 0; i < numChannels; i++ )
|
|
{
|
|
enAnim->channelList.AddChannel( m_channelNames.RegisterChannel( MSG_ReadString( &msg ) ) );
|
|
}
|
|
|
|
enAnim->channelList.PackChannels();
|
|
return enAnim;
|
|
}
|
|
|
|
skelAnimDataGameHeader_t *skeletor_c::LoadProcessedAnimEx( const char *path, void *buffer, int len, const char *name )
|
|
{
|
|
skelAnimDataGameHeader_t *enAnim;
|
|
int i;
|
|
msg_t msg;
|
|
int numChannels;
|
|
skelAnimGameFrame_t *newFrame;
|
|
|
|
MSG_Init( &msg, ( byte * )buffer, len );
|
|
msg.cursize = len;
|
|
MSG_BeginReading( &msg );
|
|
|
|
numChannels = MSG_ReadShort( &msg );
|
|
enAnim = skelAnimDataGameHeader_t::AllocRLEChannelData( numChannels );
|
|
enAnim->channelList.ZeroChannels();
|
|
enAnim->flags = MSG_ReadLong( &msg );
|
|
enAnim->frameTime = MSG_ReadFloat( &msg );
|
|
enAnim->totalDelta[ 0 ] = MSG_ReadFloat( &msg );
|
|
enAnim->totalDelta[ 1 ] = MSG_ReadFloat( &msg );
|
|
enAnim->totalDelta[ 2 ] = MSG_ReadFloat( &msg );
|
|
enAnim->totalAngleDelta = MSG_ReadFloat( &msg );
|
|
enAnim->numFrames = MSG_ReadLong( &msg );
|
|
enAnim->bHasDelta = MSG_ReadByte( &msg ) != 0;
|
|
enAnim->bHasUpper = MSG_ReadByte( &msg ) != 0;
|
|
enAnim->bHasMorph = MSG_ReadByte( &msg ) != 0;
|
|
|
|
for( i = 0; i < enAnim->nTotalChannels; i++ )
|
|
{
|
|
enAnim->channelList.AddChannel( m_channelNames.RegisterChannel( MSG_ReadString( &msg ) ) );
|
|
}
|
|
|
|
enAnim->channelList.PackChannels();
|
|
|
|
newFrame = ( skelAnimGameFrame_t * )Skel_Alloc( enAnim->numFrames * sizeof( skelAnimGameFrame_t ) );
|
|
enAnim->m_frame = newFrame;
|
|
|
|
for( i = 0; i < enAnim->numFrames; i++ )
|
|
{
|
|
newFrame->bounds[ 0 ][ 0 ] = MSG_ReadFloat( &msg );
|
|
newFrame->bounds[ 0 ][ 1 ] = MSG_ReadFloat( &msg );
|
|
newFrame->bounds[ 0 ][ 2 ] = MSG_ReadFloat( &msg );
|
|
newFrame->bounds[ 1 ][ 0 ] = MSG_ReadFloat( &msg );
|
|
newFrame->bounds[ 1 ][ 1 ] = MSG_ReadFloat( &msg );
|
|
newFrame->bounds[ 1 ][ 2 ] = MSG_ReadFloat( &msg );
|
|
newFrame->radius = MSG_ReadFloat( &msg );
|
|
newFrame->delta[ 0 ] = MSG_ReadFloat( &msg );
|
|
newFrame->delta[ 1 ] = MSG_ReadFloat( &msg );
|
|
newFrame->delta[ 2 ] = MSG_ReadFloat( &msg );
|
|
newFrame->angleDelta = MSG_ReadFloat( &msg );
|
|
newFrame->pChannels = NULL;
|
|
newFrame++;
|
|
}
|
|
|
|
enAnim->bounds[ 0 ][ 0 ] = MSG_ReadFloat( &msg );
|
|
enAnim->bounds[ 0 ][ 1 ] = MSG_ReadFloat( &msg );
|
|
enAnim->bounds[ 0 ][ 2 ] = MSG_ReadFloat( &msg );
|
|
enAnim->bounds[ 1 ][ 0 ] = MSG_ReadFloat( &msg );
|
|
enAnim->bounds[ 1 ][ 1 ] = MSG_ReadFloat( &msg );
|
|
enAnim->bounds[ 1 ][ 2 ] = MSG_ReadFloat( &msg );
|
|
ReadEncodedFramesEx( &msg, enAnim );
|
|
|
|
return enAnim;
|
|
}
|