593 lines
14 KiB
C++
593 lines
14 KiB
C++
#include "hierchnk.hpp"
|
|
#include "Animobs.hpp"
|
|
#include "list_tem.hpp"
|
|
#include <math.h>
|
|
|
|
//macro for helping to force inclusion of chunks when using libraries
|
|
FORCE_CHUNK_INCLUDE_IMPLEMENT(animobs)
|
|
|
|
RIF_IMPLEMENT_DYNCREATE("OBASEQFR",Object_Animation_Sequence_Frame_Chunk)
|
|
|
|
void Object_Animation_Sequence_Frame_Chunk::fill_data_block (char *data_start)
|
|
{
|
|
strncpy (data_start, identifier, 8);
|
|
|
|
data_start += 8;
|
|
|
|
*((int *) data_start) = chunk_size;
|
|
|
|
data_start += 4;
|
|
|
|
|
|
*((float *) data_start) = orientation.x;
|
|
data_start += 4;
|
|
*((float *) data_start) = orientation.y;
|
|
data_start += 4;
|
|
*((float *) data_start) = orientation.z;
|
|
data_start += 4;
|
|
*((float *) data_start) = orientation.w;
|
|
data_start += 4;
|
|
|
|
*((int *) data_start) = transform.x;
|
|
data_start += 4;
|
|
*((int *) data_start) = transform.y;
|
|
data_start += 4;
|
|
*((int *) data_start) = transform.z;
|
|
data_start += 4;
|
|
|
|
*((int *) data_start) = at_frame_no;
|
|
data_start += 4;
|
|
|
|
*((int *) data_start) = frame_ref_no;
|
|
data_start += 4;
|
|
|
|
*((int *) data_start) = flags;
|
|
data_start += 4;
|
|
|
|
*(int*) data_start=num_extra_data;
|
|
data_start+=4;
|
|
|
|
for (int i=0; i<num_extra_data; i++)
|
|
{
|
|
*((int *) data_start) = extra_data[i];
|
|
data_start += 4;
|
|
}
|
|
|
|
}
|
|
|
|
#if UseOldChunkLoader
|
|
Object_Animation_Sequence_Frame_Chunk::Object_Animation_Sequence_Frame_Chunk (Object_Animation_Sequence_Chunk * parent,const char *data_start, size_t)
|
|
: Chunk (parent, "OBASEQFR")
|
|
{
|
|
orientation.x = -(*(double *) data_start);
|
|
data_start += 8;
|
|
orientation.y = -(*(double *) data_start);
|
|
data_start += 8;
|
|
orientation.z = -(*(double *) data_start);
|
|
data_start += 8;
|
|
orientation.w = (*(double *) data_start);
|
|
data_start += 8;
|
|
|
|
transform.x = *((double *) data_start);
|
|
data_start += 8;
|
|
transform.y = *((double *) data_start);
|
|
data_start += 8;
|
|
transform.z = *((double *) data_start);
|
|
data_start += 8;
|
|
|
|
at_frame_no = *((int *) data_start);
|
|
data_start += 4;
|
|
|
|
frame_ref_no = *((int *) data_start);
|
|
data_start += 4;
|
|
|
|
flags = *((int *) data_start);
|
|
data_start += 4;
|
|
|
|
num_extra_data=0;
|
|
extra_data=0;
|
|
|
|
}
|
|
#else
|
|
Object_Animation_Sequence_Frame_Chunk::Object_Animation_Sequence_Frame_Chunk (Chunk_With_Children * parent,const char *data_start, size_t)
|
|
: Chunk (parent, "OBASEQFR")
|
|
{
|
|
orientation.x = *((float *) data_start);
|
|
data_start += 4;
|
|
orientation.y = *((float *) data_start);
|
|
data_start += 4;
|
|
orientation.z = *((float *) data_start);
|
|
data_start += 4;
|
|
orientation.w = *((float *) data_start);
|
|
data_start += 4;
|
|
|
|
transform.x = *((int *) data_start);
|
|
data_start += 4;
|
|
transform.y = *((int *) data_start);
|
|
data_start += 4;
|
|
transform.z = *((int *) data_start);
|
|
data_start += 4;
|
|
|
|
at_frame_no = *((int *) data_start);
|
|
data_start += 4;
|
|
|
|
frame_ref_no = *((int *) data_start);
|
|
data_start += 4;
|
|
|
|
flags = *((int *) data_start);
|
|
data_start += 4;
|
|
|
|
num_extra_data=*(int*) data_start;
|
|
data_start+=4;
|
|
|
|
if(num_extra_data)
|
|
extra_data=new int[num_extra_data];
|
|
else
|
|
extra_data=0;
|
|
|
|
|
|
for (int i=0; i<num_extra_data; i++)
|
|
{
|
|
extra_data[i] = *((int *) data_start);
|
|
data_start += 4;
|
|
}
|
|
|
|
}
|
|
#endif
|
|
|
|
void Object_Animation_Sequence_Frame_Chunk::set_sound_index(int ind)
|
|
{
|
|
if(ind>=0 && ind<=127)
|
|
{
|
|
flags &=~HierarchyFrame_SoundIndexMask;
|
|
flags |= (ind<<24);
|
|
}
|
|
}
|
|
|
|
RIF_IMPLEMENT_DYNCREATE("OBASEQHD",Object_Animation_Sequence_Header_Chunk)
|
|
|
|
void Object_Animation_Sequence_Header_Chunk::fill_data_block (char *data_start)
|
|
{
|
|
strncpy (data_start, identifier, 8);
|
|
|
|
data_start += 8;
|
|
|
|
*((int *) data_start) = chunk_size;
|
|
|
|
data_start += 4;
|
|
|
|
*((int *) data_start) = num_frames;
|
|
data_start += 4;
|
|
|
|
*((int *) data_start) = sequence_number;
|
|
data_start += 4;
|
|
|
|
*((int *) data_start) = sub_sequence_number;
|
|
data_start += 4;
|
|
|
|
*(int*)data_start=num_extra_data;
|
|
data_start+=4;
|
|
|
|
for (int i=0; i<num_extra_data; i++)
|
|
{
|
|
*((int *) data_start) = extra_data[i];
|
|
data_start += 4;
|
|
}
|
|
|
|
if (sequence_name)
|
|
{
|
|
sprintf (data_start, "%s", sequence_name);
|
|
}
|
|
else
|
|
{
|
|
*data_start = 0;
|
|
}
|
|
|
|
}
|
|
|
|
Object_Animation_Sequence_Header_Chunk::~Object_Animation_Sequence_Header_Chunk()
|
|
{
|
|
if (sequence_name)
|
|
delete sequence_name;
|
|
if(extra_data)
|
|
delete extra_data;
|
|
}
|
|
|
|
|
|
#if UseOldChunkLoader
|
|
Object_Animation_Sequence_Header_Chunk::Object_Animation_Sequence_Header_Chunk (Chunk_With_Children * parent,const char * data_start, size_t)
|
|
: Chunk (parent, "OBASEQHD"), sequence_name (0)
|
|
{
|
|
num_frames = *((int *) data_start);
|
|
data_start += 4;
|
|
|
|
sequence_number = *((int *) data_start);
|
|
data_start += 4;
|
|
|
|
sub_sequence_number = *((int *) data_start);
|
|
data_start += 4;
|
|
|
|
num_extra_data=0;
|
|
extra_data=0;
|
|
data_start+=40;
|
|
|
|
if (strlen(data_start))
|
|
{
|
|
sequence_name = new char [strlen(data_start) + 1];
|
|
strcpy (sequence_name, data_start);
|
|
}
|
|
}
|
|
#else
|
|
Object_Animation_Sequence_Header_Chunk::Object_Animation_Sequence_Header_Chunk (Chunk_With_Children * parent,const char * data_start, size_t)
|
|
: Chunk (parent, "OBASEQHD"), sequence_name (0)
|
|
{
|
|
num_frames = *((int *) data_start);
|
|
data_start += 4;
|
|
|
|
sequence_number = *((int *) data_start);
|
|
data_start += 4;
|
|
|
|
sub_sequence_number = *((int *) data_start);
|
|
data_start += 4;
|
|
|
|
num_extra_data=*(int*) data_start;
|
|
data_start+=4;
|
|
|
|
if(num_extra_data)
|
|
extra_data=new int[num_extra_data];
|
|
else
|
|
extra_data=0;
|
|
|
|
|
|
for (int i=0; i<num_extra_data; i++)
|
|
{
|
|
extra_data[i] = *((int *) data_start);
|
|
data_start += 4;
|
|
}
|
|
|
|
|
|
if (strlen(data_start))
|
|
{
|
|
sequence_name = new char [strlen(data_start) + 1];
|
|
strcpy (sequence_name, data_start);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
Object_Animation_Sequence_Header_Chunk * Object_Animation_Sequence_Chunk::get_header()
|
|
{
|
|
return(Object_Animation_Sequence_Header_Chunk *) lookup_single_child("OBASEQHD");
|
|
}
|
|
|
|
void Object_Animation_Sequence_Chunk::get_frames(List <Object_Animation_Sequence_Frame_Chunk*> *pList)
|
|
{
|
|
List <Chunk *> cl;
|
|
lookup_child ("OBASEQFR",cl);
|
|
|
|
for (LIF<Chunk *> cli(&cl); !cli.done(); cli.next())
|
|
{
|
|
pList->add_entry((Object_Animation_Sequence_Frame_Chunk *)cli());
|
|
}
|
|
|
|
}
|
|
|
|
////////////////////////////////
|
|
|
|
RIF_IMPLEMENT_DYNCREATE("OBANSEQS",Object_Animation_Sequences_Chunk)
|
|
|
|
void Object_Animation_Sequences_Chunk::list_sequences(List <Object_Animation_Sequence_Chunk *> * pList)
|
|
{
|
|
List <Chunk *> cl;
|
|
lookup_child ("OBANSEQC",cl);
|
|
|
|
for (LIF<Chunk *> cli(&cl); !cli.done(); cli.next())
|
|
{
|
|
pList->add_entry((Object_Animation_Sequence_Chunk *)cli());
|
|
}
|
|
}
|
|
|
|
|
|
Object_Animation_Sequence_Chunk::Object_Animation_Sequence_Chunk(Object_Animation_Sequences_Chunk* parent,Object_Animation_Sequence_Chunk* template_seq,ChunkQuat & orient ,ChunkVectorInt & trans)
|
|
:Chunk_With_Children (parent, "OBANSEQC")
|
|
{
|
|
Object_Animation_Sequence_Header_Chunk* template_header=template_seq->get_header();
|
|
Object_Animation_Sequence_Header_Chunk* header=new Object_Animation_Sequence_Header_Chunk(this);
|
|
|
|
header->num_frames=65536;
|
|
header->sequence_number=template_header->sequence_number;
|
|
header->sub_sequence_number=template_header->sub_sequence_number;
|
|
header->sequence_name=new char[strlen(template_header->sequence_name)+1];
|
|
strcpy(header->sequence_name,template_header->sequence_name);
|
|
|
|
Object_Animation_Sequence_Frame_Chunk* oasfc=new Object_Animation_Sequence_Frame_Chunk(this);
|
|
|
|
oasfc->orientation=orient;
|
|
oasfc->transform=trans;
|
|
oasfc->at_frame_no=0;
|
|
oasfc->frame_ref_no=0;
|
|
|
|
//see if template sequence is a delta sequence
|
|
List<Object_Animation_Sequence_Frame_Chunk*> framelist;
|
|
template_seq->get_frames(&framelist);
|
|
while(framelist.size())
|
|
{
|
|
if(framelist.first_entry()->flags & HierarchyFrameFlag_DeltaFrame)
|
|
{
|
|
oasfc->flags=HierarchyFrameFlag_DeltaFrame;
|
|
break;
|
|
}
|
|
framelist.delete_first_entry();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
Object_Animation_Sequence_Chunk * Object_Animation_Sequences_Chunk::get_sequence (int num, int subnum)
|
|
{
|
|
List <Object_Animation_Sequence_Chunk *> seq_list;
|
|
list_sequences(&seq_list);
|
|
|
|
for (LIF<Object_Animation_Sequence_Chunk *> sli(&seq_list); !sli.done(); sli.next())
|
|
{
|
|
Object_Animation_Sequence_Header_Chunk * oashc = sli()->get_header();
|
|
if (oashc)
|
|
{
|
|
if (oashc->sequence_number == num && oashc->sub_sequence_number == subnum)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!sli.done())
|
|
{
|
|
return(sli());
|
|
}
|
|
else
|
|
{
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
int Object_Animation_Sequence_Chunk::get_sequence_time()
|
|
{
|
|
Object_Animation_Sequence_Time_Chunk* time_chunk=(Object_Animation_Sequence_Time_Chunk*)lookup_single_child("OBASEQTM");
|
|
if(time_chunk)
|
|
{
|
|
return time_chunk->sequence_time;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int Object_Animation_Sequence_Chunk::get_sequence_speed()
|
|
{
|
|
Object_Animation_Sequence_Speed_Chunk* speed_chunk=(Object_Animation_Sequence_Speed_Chunk*)lookup_single_child("OBASEQSP");
|
|
if(speed_chunk)
|
|
{
|
|
return speed_chunk->sequence_speed;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
BOOL Object_Animation_Sequence_Chunk::get_sequence_vector(ChunkVectorFloat* direction)
|
|
{
|
|
if(!direction) return FALSE;
|
|
|
|
//default direction is forwards
|
|
direction->x=0;
|
|
direction->y=0;
|
|
direction->z=1;
|
|
|
|
|
|
Object_Animation_Sequence_Speed_Chunk* speed_chunk=(Object_Animation_Sequence_Speed_Chunk*)lookup_single_child("OBASEQSP");
|
|
if(speed_chunk)
|
|
{
|
|
double radian_angle=(speed_chunk->angle/360.0)*2*3.1415278;
|
|
direction->x =(float) sin(radian_angle);
|
|
direction->z =(float) cos(radian_angle);
|
|
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
int Object_Animation_Sequence_Chunk::get_sequence_flags()
|
|
{
|
|
Object_Animation_Sequence_Flags_Chunk* flag_chunk=(Object_Animation_Sequence_Flags_Chunk*)lookup_single_child("OBASEQFL");
|
|
if(flag_chunk)
|
|
{
|
|
return flag_chunk->flags;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void Object_Animation_Sequence_Chunk::set_sequence_flags(int new_flags)
|
|
{
|
|
//find existing flag_chunk , or create a new one
|
|
Object_Animation_Sequence_Flags_Chunk* flag_chunk=(Object_Animation_Sequence_Flags_Chunk*)lookup_single_child("OBASEQFL");
|
|
if(flag_chunk)
|
|
{
|
|
//set the flags
|
|
flag_chunk->flags = new_flags;
|
|
}
|
|
else
|
|
{
|
|
//create a new chunk then
|
|
new Object_Animation_Sequence_Flags_Chunk(this,new_flags);
|
|
}
|
|
}
|
|
|
|
Hierarchy_Bounding_Box_Chunk* Object_Animation_Sequence_Chunk::get_bounding_box()
|
|
{
|
|
return (Hierarchy_Bounding_Box_Chunk*)lookup_single_child("HIERBBOX");
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/*--------------------------------------**
|
|
** Object_Animation_Sequence_Time_Chunk **
|
|
**--------------------------------------*/
|
|
|
|
RIF_IMPLEMENT_DYNCREATE("OBASEQTM",Object_Animation_Sequence_Time_Chunk)
|
|
|
|
Object_Animation_Sequence_Time_Chunk::Object_Animation_Sequence_Time_Chunk (Chunk_With_Children * parent,const char * data_start, size_t)
|
|
: Chunk (parent, "OBASEQTM")
|
|
{
|
|
sequence_time=*(unsigned int*) data_start;
|
|
}
|
|
|
|
void Object_Animation_Sequence_Time_Chunk::fill_data_block(char* data_start)
|
|
{
|
|
strncpy (data_start, identifier, 8);
|
|
data_start += 8;
|
|
*((int *) data_start) = chunk_size;
|
|
data_start += 4;
|
|
|
|
*(unsigned int*) data_start = sequence_time;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/*---------------------------------------**
|
|
** Object_Animation_Sequence_Speed_Chunk **
|
|
**---------------------------------------*/
|
|
|
|
RIF_IMPLEMENT_DYNCREATE("OBASEQSP",Object_Animation_Sequence_Speed_Chunk)
|
|
|
|
Object_Animation_Sequence_Speed_Chunk::Object_Animation_Sequence_Speed_Chunk (Chunk_With_Children * parent,const char * data, size_t)
|
|
: Chunk (parent, "OBASEQSP")
|
|
{
|
|
CHUNK_EXTRACT(sequence_speed,int)
|
|
CHUNK_EXTRACT(angle,int)
|
|
CHUNK_EXTRACT(spare,int)
|
|
}
|
|
|
|
void Object_Animation_Sequence_Speed_Chunk::fill_data_block(char* data)
|
|
{
|
|
CHUNK_FILL_START
|
|
CHUNK_FILL(sequence_speed,int)
|
|
CHUNK_FILL(angle,int)
|
|
CHUNK_FILL(spare,int)
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/*---------------------------------------**
|
|
** Object_Animation_Sequence_Flags_Chunk **
|
|
**---------------------------------------*/
|
|
|
|
|
|
RIF_IMPLEMENT_DYNCREATE("OBASEQFL",Object_Animation_Sequence_Flags_Chunk)
|
|
|
|
Object_Animation_Sequence_Flags_Chunk::Object_Animation_Sequence_Flags_Chunk (Chunk_With_Children * parent,const char * data, size_t)
|
|
: Chunk (parent, "OBASEQFL")
|
|
{
|
|
CHUNK_EXTRACT(flags,int)
|
|
}
|
|
|
|
void Object_Animation_Sequence_Flags_Chunk::fill_data_block(char* data)
|
|
{
|
|
CHUNK_FILL_START
|
|
CHUNK_FILL(flags,int)
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
RIF_IMPLEMENT_DYNCREATE("OBANALLS",Object_Animation_All_Sequence_Chunk)
|
|
|
|
Object_Animation_All_Sequence_Chunk::Object_Animation_All_Sequence_Chunk(Chunk_With_Children* parent)
|
|
:Chunk(parent,"OBANALLS")
|
|
{
|
|
num_sequences=0;
|
|
sequences=0;
|
|
}
|
|
|
|
Object_Animation_All_Sequence_Chunk::Object_Animation_All_Sequence_Chunk(Chunk_With_Children * const parent,const char * data, const size_t)
|
|
:Chunk(parent,"OBANALLS")
|
|
{
|
|
num_sequences=*(int*)data;
|
|
data+=4;
|
|
|
|
if(num_sequences) sequences=new Object_Animation_Sequence[num_sequences];
|
|
else sequences=0;
|
|
|
|
for(int i=0;i<num_sequences;i++)
|
|
{
|
|
Object_Animation_Sequence* seq=&sequences[i];
|
|
seq->num_frames=*(int*)data;
|
|
data+=4;
|
|
seq->sequence_number=*(int*)data;
|
|
data+=4;
|
|
seq->sub_sequence_number=*(int*)data;
|
|
data+=4;
|
|
seq->sequence_time=*(int*)data;
|
|
data+=4;
|
|
|
|
if(seq->num_frames) seq->frames=new Object_Animation_Frame[seq->num_frames];
|
|
else seq->frames=0;
|
|
|
|
for(unsigned j=0;j<seq->num_frames;j++)
|
|
{
|
|
seq->frames[j]=*(Object_Animation_Frame*)data;
|
|
data+=sizeof(Object_Animation_Frame);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Object_Animation_All_Sequence_Chunk::fill_data_block(char* data)
|
|
{
|
|
strncpy (data, identifier, 8);
|
|
data += 8;
|
|
*((int *) data) = chunk_size;
|
|
data += 4;
|
|
|
|
*(int*)data=num_sequences;
|
|
data+=4;
|
|
|
|
for(int i=0;i<num_sequences;i++)
|
|
{
|
|
Object_Animation_Sequence* seq=&sequences[i];
|
|
*(int*)data=seq->num_frames;
|
|
data+=4;
|
|
*(int*)data=seq->sequence_number;
|
|
data+=4;
|
|
*(int*)data=seq->sub_sequence_number;
|
|
data+=4;
|
|
*(int*)data=seq->sequence_time;
|
|
data+=4;
|
|
|
|
for(unsigned j=0;j<seq->num_frames;j++)
|
|
{
|
|
*(Object_Animation_Frame*)data=seq->frames[j];
|
|
data+=sizeof(Object_Animation_Frame);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
size_t Object_Animation_All_Sequence_Chunk::size_chunk()
|
|
{
|
|
chunk_size=12+4;
|
|
chunk_size+=num_sequences*16;
|
|
for(int i=0;i<num_sequences;i++)
|
|
{
|
|
chunk_size+=sequences[i].num_frames*sizeof(Object_Animation_Frame);
|
|
}
|
|
return chunk_size;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//loader for Object_Animation_Sequences_Chunk
|
|
CHUNK_WITH_CHILDREN_LOADER("OBANSEQS",Object_Animation_Sequences_Chunk)
|
|
|
|
|
|
|
|
//Object_Animation_Sequence_Chunk
|
|
|
|
RIF_IMPLEMENT_DYNCREATE("OBANSEQC",Object_Animation_Sequence_Chunk)
|
|
//loader for Object_Animation_Sequence_Chunk
|
|
CHUNK_WITH_CHILDREN_LOADER("OBANSEQC",Object_Animation_Sequence_Chunk)
|