leocad/common/object.cpp

243 lines
4.4 KiB
C++
Raw Normal View History

#include "lc_global.h"
2012-03-29 03:10:55 +02:00
#include "lc_math.h"
2011-09-07 23:06:51 +02:00
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include "project.h"
#include "object.h"
#include "lc_file.h"
2011-09-07 23:06:51 +02:00
#include "lc_application.h"
#define LC_KEY_SAVE_VERSION 1 // LeoCAD 0.73
2014-05-01 20:42:11 +02:00
lcObject::lcObject(lcObjectType ObjectType)
2011-09-07 23:06:51 +02:00
{
m_pInstructionKeys = NULL;
2011-09-07 23:06:51 +02:00
mObjectType = ObjectType;
m_pKeyValues = NULL;
2011-09-07 23:06:51 +02:00
}
2014-05-01 20:42:11 +02:00
lcObject::~lcObject()
2011-09-07 23:06:51 +02:00
{
delete []m_pKeyValues;
RemoveKeys();
2011-09-07 23:06:51 +02:00
}
2014-05-01 20:42:11 +02:00
bool lcObject::FileLoad(lcFile& file)
2011-09-07 23:06:51 +02:00
{
2012-03-23 00:44:56 +01:00
lcuint8 version = file.ReadU8();
2011-09-07 23:06:51 +02:00
if (version > LC_KEY_SAVE_VERSION)
return false;
lcuint16 time;
float param[4];
lcuint8 type;
lcuint32 n;
2012-03-23 00:44:56 +01:00
file.ReadU32(&n, 1);
2011-09-07 23:06:51 +02:00
while (n--)
{
2012-03-23 00:44:56 +01:00
file.ReadU16(&time, 1);
file.ReadFloats(param, 4);
file.ReadU8(&type, 1);
2011-09-07 23:06:51 +02:00
2014-01-30 04:13:34 +01:00
ChangeKey(time, true, param, type);
2011-09-07 23:06:51 +02:00
}
2012-03-23 00:44:56 +01:00
file.ReadU32(&n, 1);
2011-09-07 23:06:51 +02:00
while (n--)
{
2012-03-23 00:44:56 +01:00
file.ReadU16(&time, 1);
file.ReadFloats(param, 4);
file.ReadU8(&type, 1);
2011-09-07 23:06:51 +02:00
}
return true;
}
2014-05-01 20:42:11 +02:00
void lcObject::FileSave(lcFile& file) const
2011-09-07 23:06:51 +02:00
{
2014-07-06 08:04:09 +02:00
LC_OBJECT_KEY *node;
lcuint32 n;
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
file.WriteU8(LC_KEY_SAVE_VERSION);
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
for (n = 0, node = m_pInstructionKeys; node; node = node->next)
n++;
file.WriteU32(n);
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
for (node = m_pInstructionKeys; node; node = node->next)
{
lcuint16 Step = lcMin(node->Step, 0xFFFFU);
file.WriteU16(Step);
file.WriteFloats(node->param, 4);
file.WriteU8(node->type);
}
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
file.WriteU32(0);
2011-09-07 23:06:51 +02:00
}
// =============================================================================
// Key handling
2014-07-06 08:04:09 +02:00
static LC_OBJECT_KEY* AddNode(LC_OBJECT_KEY *node, lcStep Step, unsigned char nType)
2011-09-07 23:06:51 +02:00
{
2012-08-17 01:50:40 +02:00
LC_OBJECT_KEY* newnode = (LC_OBJECT_KEY*)malloc(sizeof(LC_OBJECT_KEY));
2011-09-07 23:06:51 +02:00
if (node)
{
newnode->next = node->next;
node->next = newnode;
}
else
newnode->next = NULL;
newnode->type = nType;
2014-07-06 08:04:09 +02:00
newnode->Step = Step;
2011-09-07 23:06:51 +02:00
newnode->param[0] = newnode->param[1] = newnode->param[2] = newnode->param[3] = 0;
return newnode;
}
2014-05-01 20:42:11 +02:00
void lcObject::RegisterKeys(float *values[], LC_OBJECT_KEY_INFO* info, int count)
2011-09-07 23:06:51 +02:00
{
int i;
m_pKeyValues = new float* [count];
for (i = 0; i < count; i++)
m_pKeyValues[i] = values[i];
2012-08-17 01:50:40 +02:00
m_pInstructionKeys = AddNode(NULL, 1, 0);
2011-09-07 23:06:51 +02:00
for (i = count-1; i > 0; i--)
2014-01-30 04:13:34 +01:00
AddNode(m_pInstructionKeys, 1, i);
2011-09-07 23:06:51 +02:00
m_pKeyInfo = info;
m_nKeyInfoCount = count;
}
2014-05-01 20:42:11 +02:00
void lcObject::RemoveKeys()
2011-09-07 23:06:51 +02:00
{
LC_OBJECT_KEY *node, *prev;
for (node = m_pInstructionKeys; node;)
{
prev = node;
node = node->next;
2012-08-17 01:50:40 +02:00
free(prev);
2011-09-07 23:06:51 +02:00
}
}
2014-07-06 08:04:09 +02:00
void lcObject::ChangeKey(lcStep Step, bool AddKey, const float *param, unsigned char nKeyType)
2011-09-07 23:06:51 +02:00
{
2014-07-06 08:04:09 +02:00
LC_OBJECT_KEY *node, *poskey = NULL, *newpos = NULL;
node = m_pInstructionKeys;
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
while (node)
{
if ((node->Step <= Step) && (node->type == nKeyType))
poskey = node;
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
node = node->next;
}
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
if (AddKey)
{
if (poskey)
{
if (poskey->Step != Step)
newpos = AddNode(poskey, Step, nKeyType);
}
else
newpos = AddNode(poskey, Step, nKeyType);
}
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
if (newpos == NULL)
newpos = poskey;
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
for (int i = 0; i < m_pKeyInfo[nKeyType].size; i++)
newpos->param[i] = param[i];
2011-09-07 23:06:51 +02:00
}
2014-07-06 08:04:09 +02:00
void lcObject::CalculateKeys(lcStep Step)
2011-09-07 23:06:51 +02:00
{
2014-07-06 08:04:09 +02:00
LC_OBJECT_KEY* prev[32];
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
for (LC_OBJECT_KEY* node = m_pInstructionKeys; node; node = node->next)
if (node->Step <= Step)
prev[node->type] = node;
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
for (int i = 0; i < m_nKeyInfoCount; i++)
{
LC_OBJECT_KEY *p = prev[i];
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
for (int j = 0; j < m_pKeyInfo[i].size; j++)
m_pKeyValues[i][j] = p->param[j];
}
2011-09-07 23:06:51 +02:00
}
2014-07-06 08:04:09 +02:00
void lcObject::InsertTime(lcStep Start, lcStep Time)
2011-09-07 23:06:51 +02:00
{
2014-07-06 08:04:09 +02:00
LC_OBJECT_KEY *node, *prev = NULL;
bool end[32];
for (int i = 0; i < m_nKeyInfoCount; i++)
end[i] = false;
2011-09-07 23:06:51 +02:00
2014-01-30 04:13:34 +01:00
node = m_pInstructionKeys;
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
for (; node != NULL; prev = node, node = node->next)
2011-09-07 23:06:51 +02:00
{
2014-07-06 08:04:09 +02:00
// skip everything before the start time
if ((node->Step < Start) || (node->Step == 1))
continue;
// there's already a key at the end, delete this one
if (end[node->type])
2011-09-07 23:06:51 +02:00
{
2014-07-06 08:04:09 +02:00
prev->next = node->next;
free(node);
node = prev;
continue;
2011-09-07 23:06:51 +02:00
}
2014-07-06 08:04:09 +02:00
if (node->Step >= LC_STEP_MAX - Time)
{
node->Step = LC_STEP_MAX;
end[node->type] = true;
}
else
node->Step += Time;
2011-09-07 23:06:51 +02:00
}
}
2014-07-06 08:04:09 +02:00
void lcObject::RemoveTime(lcStep Start, lcStep Time)
2011-09-07 23:06:51 +02:00
{
2014-07-06 08:04:09 +02:00
LC_OBJECT_KEY *node = m_pInstructionKeys, *prev = NULL;
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
for (; node != NULL; prev = node, node = node->next)
{
// skip everything before the start time
if ((node->Step < Start) || (node->Step == 1))
continue;
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
if (node->Step < Start + Time)
{
// delete this key
prev->next = node->next;
free(node);
node = prev;
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
continue;
}
2011-09-07 23:06:51 +02:00
2014-07-06 08:04:09 +02:00
node->Step -= Time;
if (node->Step < 1)
node->Step = 1;
}
2011-09-07 23:06:51 +02:00
}