avp/3dc/win95/animobs.cpp

594 lines
14 KiB
C++
Raw Normal View History

#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)