summaryrefslogtreecommitdiff
path: root/common/object.cpp
diff options
context:
space:
mode:
authorleo2000-11-12 20:03:48 +0000
committerleo2000-11-12 20:03:48 +0000
commit94ae70d4d252cde37bdc605a328e1fed811f2d96 (patch)
tree963b125283f8a256fcb737c9b66c13f6e855cd63 /common/object.cpp
parent677a64d9d764ed6e37c3f7b1b9ec29239de37a6b (diff)
Moved all keyframer functions to the Object class
git-svn-id: http://svn.leocad.org/trunk@160 c7d43263-9d01-0410-8a33-9dba5d9f93d6
Diffstat (limited to 'common/object.cpp')
-rwxr-xr-xcommon/object.cpp262
1 files changed, 262 insertions, 0 deletions
diff --git a/common/object.cpp b/common/object.cpp
index a26d2d5..1dd8d44 100755
--- a/common/object.cpp
+++ b/common/object.cpp
@@ -7,6 +7,9 @@
#include "object.h"
#include "matrix.h"
#include "vector.h"
+#include "file.h"
+
+#define LC_KEY_SAVE_VERSION 1 // LeoCAD 0.73
// =============================================================================
// Static functions
@@ -54,7 +57,12 @@ Object::Object (LC_OBJECT_TYPE nType)
{
// m_nState = 0;
// m_strName[0] = '\0';
+
+ m_pAnimationKeys = NULL;
+ m_pInstructionKeys = NULL;
+
m_nObjectType = nType;
+ m_pKeyValues = NULL;
// m_pParent = NULL;
// m_pNext = NULL;
@@ -63,7 +71,261 @@ Object::Object (LC_OBJECT_TYPE nType)
Object::~Object ()
{
+ delete []m_pKeyValues;
+ RemoveKeys ();
+}
+
+bool Object::FileLoad (File& file)
+{
+ unsigned char version;
+
+ file.ReadByte (&version, 1);
+ if (version > LC_KEY_SAVE_VERSION)
+ return false;
+
+ unsigned short time;
+ float param[4];
+ unsigned char type;
+ unsigned long n;
+
+ file.ReadLong (&n, 1);
+ while (n--)
+ {
+ file.ReadShort (&time, 1);
+ file.Read (param, sizeof (float[4]));
+ file.ReadByte (&type, 1);
+
+ ChangeKey (time, false, true, param, type);
+ }
+
+ file.ReadLong (&n, 1);
+ while (n--)
+ {
+ file.ReadShort (&time, 1);
+ file.Read (param, sizeof (float[4]));
+ file.ReadByte (&type, 1);
+
+ ChangeKey (time, true, true, param, type);
+ }
+
+ return true;
+}
+
+void Object::FileSave (File& file)
+{
+ unsigned char version = LC_KEY_SAVE_VERSION;
+ LC_OBJECT_KEY *node;
+ unsigned long n;
+
+ file.WriteByte (&version, 1);
+
+ for (n = 0, node = m_pInstructionKeys; node; node = node->next)
+ n++;
+ file.WriteLong (&n, 1);
+
+ for (node = m_pInstructionKeys; node; node = node->next)
+ {
+ file.WriteShort (&node->time, 1);
+ file.Write (node->param, sizeof (float[4]));
+ file.WriteByte (&node->type, 1);
+ }
+
+ for (n = 0, node = m_pAnimationKeys; node; node = node->next)
+ n++;
+ file.WriteLong (&n, 1);
+
+ for (node = m_pAnimationKeys; node; node = node->next)
+ {
+ file.WriteShort (&node->time, 1);
+ file.Write (node->param, sizeof (float[4]));
+ file.WriteByte (&node->type, 1);
+ }
+}
+
+// =============================================================================
+// Key handling
+
+static LC_OBJECT_KEY* AddNode (LC_OBJECT_KEY *node, unsigned short nTime, unsigned char nType)
+{
+ LC_OBJECT_KEY* newnode = (LC_OBJECT_KEY*)malloc (sizeof (LC_OBJECT_KEY));
+
+ if (node)
+ {
+ newnode->next = node->next;
+ node->next = newnode;
+ }
+ else
+ newnode->next = NULL;
+
+ newnode->type = nType;
+ newnode->time = nTime;
+ newnode->param[0] = newnode->param[1] = newnode->param[2] = newnode->param[3] = 0;
+
+ return newnode;
+}
+
+void Object::RegisterKeys (float *values[], LC_OBJECT_KEY_INFO* info, int count)
+{
+ int i;
+
+ m_pKeyValues = new float* [count];
+
+ for (i = 0; i < count; i++)
+ m_pKeyValues[i] = values[i];
+
+ m_pAnimationKeys = AddNode (NULL, 1, 0);
+ m_pInstructionKeys = AddNode (NULL, 1, 0);
+
+ for (i = count-1; i > 0; i--)
+ {
+ AddNode (m_pAnimationKeys, 1, i);
+ AddNode (m_pInstructionKeys, 1, i);
+ }
+
+ m_pKeyInfo = info;
+ m_nKeyInfoCount = count;
+}
+
+void Object::RemoveKeys ()
+{
+ LC_OBJECT_KEY *node, *prev;
+
+ for (node = m_pInstructionKeys; node;)
+ {
+ prev = node;
+ node = node->next;
+ free (prev);
+ }
+ for (node = m_pAnimationKeys; node;)
+ {
+ prev = node;
+ node = node->next;
+ free (prev);
+ }
+}
+
+void Object::ChangeKey (unsigned short nTime, bool bAnimation, bool bAddKey, const float *param, unsigned char nKeyType)
+{
+ LC_OBJECT_KEY *node, *poskey = NULL, *newpos = NULL;
+ if (bAnimation)
+ node = m_pAnimationKeys;
+ else
+ node = m_pInstructionKeys;
+
+ while (node)
+ {
+ if ((node->time <= nTime) &&
+ (node->type == nKeyType))
+ poskey = node;
+
+ node = node->next;
+ }
+
+ if (bAddKey)
+ {
+ if (poskey)
+ {
+ if (poskey->time != nTime)
+ newpos = AddNode(poskey, nTime, nKeyType);
+ }
+ else
+ newpos = AddNode(poskey, nTime, nKeyType);
+ }
+
+ if (newpos == NULL)
+ newpos = poskey;
+
+ for (int i = 0; i < m_pKeyInfo[nKeyType].size; i++)
+ newpos->param[i] = param[i];
+}
+
+void Object::CalculateKeys (unsigned short nTime, bool bAnimation)
+{
+ LC_OBJECT_KEY *next[m_nKeyInfoCount], *prev[m_nKeyInfoCount], *node;
+ int i, empty = m_nKeyInfoCount;
+
+ for (i = 0; i < m_nKeyInfoCount; i++)
+ next[i] = NULL;
+
+ if (bAnimation)
+ node = m_pAnimationKeys;
+ else
+ node = m_pInstructionKeys;
+
+ // Get the previous and next keys for each variable
+ while (node && empty)
+ {
+ if (node->time <= nTime)
+ {
+ prev[node->type] = node;
+ }
+ else
+ {
+ if (next[node->type] == NULL)
+ {
+ next[node->type] = node;
+ empty--;
+ }
+ }
+
+ node = node->next;
+ }
+
+ // TODO: USE KEY IN/OUT WEIGHTS
+ for (i = 0; i < m_nKeyInfoCount; i++)
+ {
+ LC_OBJECT_KEY *n = next[i], *p = prev[i];
+
+ if (bAnimation && (n != NULL) && (p->time != nTime))
+ {
+ float t = (float)(nTime - p->time)/(n->time - p->time);
+
+ for (int j = 0; j < m_pKeyInfo[i].size; j++)
+ m_pKeyValues[i][j] = p->param[j] + (n->param[j] - p->param[j])*t;
+ }
+ else
+ for (int j = 0; j < m_pKeyInfo[i].size; j++)
+ m_pKeyValues[i][j] = p->param[j];
+ }
+}
+
+void Object::CalculateSingleKey (unsigned short nTime, bool bAnimation, int keytype, float *value)
+{
+ LC_OBJECT_KEY *next = NULL, *prev = NULL, *node;
+
+ if (bAnimation)
+ node = m_pAnimationKeys;
+ else
+ node = m_pInstructionKeys;
+
+ while (node)
+ {
+ if (node->time <= nTime)
+ prev = node;
+ else
+ {
+ if (next == NULL)
+ {
+ next = node;
+ break;
+ }
+ }
+
+ node = node->next;
+ }
+
+ // TODO: USE KEY IN/OUT WEIGHTS
+ if (bAnimation && (next != NULL) && (prev->time != nTime))
+ {
+ float t = (float)(nTime - prev->time)/(next->time - prev->time);
+
+ for (int j = 0; j < m_pKeyInfo[keytype].size; j++)
+ value[j] = prev->param[j] + (next->param[j] - prev->param[j])*t;
+ }
+ else
+ for (int j = 0; j < m_pKeyInfo[keytype].size; j++)
+ value[j] = prev->param[j];
}
// =============================================================================