summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/camera.cpp523
-rw-r--r--common/camera.h30
-rw-r--r--common/light.cpp278
-rw-r--r--common/light.h35
-rwxr-xr-xcommon/object.cpp262
-rwxr-xr-xcommon/object.h45
-rw-r--r--common/piece.cpp611
-rw-r--r--common/piece.h33
8 files changed, 797 insertions, 1020 deletions
diff --git a/common/camera.cpp b/common/camera.cpp
index ed93251..28ef716 100644
--- a/common/camera.cpp
+++ b/common/camera.cpp
@@ -12,29 +12,16 @@
#include "camera.h"
#include "tr.h"
-/////////////////////////////////////////////////////////////////////////////
-// Static functions
+#define LC_CAMERA_SAVE_VERSION 6 // LeoCAD 0.73
-static GLuint _nTargetList = 0;
+GLuint Camera::m_nTargetList = 0;
-static LC_CAMERA_KEY* AddNode (LC_CAMERA_KEY *node, unsigned short nTime, unsigned char nType)
+static LC_OBJECT_KEY_INFO camera_key_info[LC_CK_COUNT] =
{
- LC_CAMERA_KEY* newnode = (LC_CAMERA_KEY*)malloc (sizeof (LC_CAMERA_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] = 0;
-
- return newnode;
-}
+ { "Camera Position", 3, LC_CK_EYE },
+ { "Camera Target", 3, LC_CK_TARGET },
+ { "Camera Up Vector", 3, LC_CK_UP }
+};
// =============================================================================
// CameraTarget class
@@ -86,28 +73,13 @@ Camera::Camera (unsigned char nType, Camera* pPrev)
{ 0,50,0 }, { 0,-50,0 }, { 10,10,5}, { 0,5,0 } };
float ups [8][3] = { { 0,0,1 }, { 0,0,1 }, { 1,0,0 }, { -1,0,0 }, { 0,0,1 },
{ 0,0,1 }, {-0.2357f, -0.2357f, 0.94281f }, { 0,0,1 } };
- LC_CAMERA_KEY* node;
Initialize();
- m_pAnimationKeys = AddNode (NULL, 1, CK_EYE);
- m_pAnimationKeys->param[0] = eyes[nType][0];
- m_pAnimationKeys->param[1] = eyes[nType][1];
- m_pAnimationKeys->param[2] = eyes[nType][2];
- node = AddNode (m_pAnimationKeys, 1, CK_TARGET);
- node = AddNode (node, 1, CK_UP);
- node->param[0] = ups[nType][0];
- node->param[1] = ups[nType][1];
- node->param[2] = ups[nType][2];
-
- m_pInstructionKeys = AddNode (NULL, 1, CK_EYE);
- m_pInstructionKeys->param[0] = eyes[nType][0];
- m_pInstructionKeys->param[1] = eyes[nType][1];
- m_pInstructionKeys->param[2] = eyes[nType][2];
- node = AddNode (m_pInstructionKeys, 1, CK_TARGET);
- node = AddNode (node, 1, CK_UP);
- node->param[0] = ups[nType][0];
- node->param[1] = ups[nType][1];
- node->param[2] = ups[nType][2];
+
+ ChangeKey (1, false, true, eyes[nType], LC_CK_EYE);
+ ChangeKey (1, false, true, ups[nType], LC_CK_UP);
+ ChangeKey (1, true, true, eyes[nType], LC_CK_EYE);
+ ChangeKey (1, true, true, ups[nType], LC_CK_UP);
strcpy (m_strName, names[nType]);
if (nType != 8)
@@ -124,8 +96,6 @@ Camera::Camera (unsigned char nType, Camera* pPrev)
Camera::Camera (const float *eye, const float *target, const float *up, Camera* pCamera)
: Object (LC_OBJECT_CAMERA)
{
- LC_CAMERA_KEY* node;
-
// Fix the up vector
Vector upvec(up), frontvec(eye[0]-target[0], eye[1]-target[1], eye[2]-target[2]), sidevec;
frontvec.Normalize();
@@ -134,31 +104,13 @@ Camera::Camera (const float *eye, const float *target, const float *up, Camera*
upvec.Normalize();
Initialize();
- m_pAnimationKeys = AddNode (NULL, 1, CK_EYE);
- m_pAnimationKeys->param[0] = eye[0];
- m_pAnimationKeys->param[1] = eye[1];
- m_pAnimationKeys->param[2] = eye[2];
- node = AddNode (m_pAnimationKeys, 1, CK_TARGET);
- node->param[0] = target[0];
- node->param[1] = target[1];
- node->param[2] = target[2];
- node = AddNode (node, 1, CK_UP);
- node->param[0] = upvec.X();
- node->param[1] = upvec.Y();
- node->param[2] = upvec.Z();
-
- m_pInstructionKeys = AddNode (NULL, 1, CK_EYE);
- m_pInstructionKeys->param[0] = eye[0];
- m_pInstructionKeys->param[1] = eye[1];
- m_pInstructionKeys->param[2] = eye[2];
- node = AddNode (m_pInstructionKeys, 1, CK_TARGET);
- node->param[0] = target[0];
- node->param[1] = target[1];
- node->param[2] = target[2];
- node = AddNode (node, 1, CK_UP);
- node->param[0] = upvec.X();
- node->param[1] = upvec.Y();
- node->param[2] = upvec.Z();
+
+ ChangeKey (1, false, true, eye, LC_CK_EYE);
+ ChangeKey (1, false, true, target, LC_CK_TARGET);
+ ChangeKey (1, false, true, upvec, LC_CK_UP);
+ ChangeKey (1, true, true, eye, LC_CK_EYE);
+ ChangeKey (1, true, true, target, LC_CK_TARGET);
+ ChangeKey (1, true, true, upvec, LC_CK_UP);
int i, max = 0;
@@ -186,8 +138,6 @@ Camera::Camera (const float *eye, const float *target, const float *up, Camera*
Camera::Camera (float ex, float ey, float ez, float tx, float ty, float tz, Camera* pCamera)
: Object (LC_OBJECT_CAMERA)
{
- LC_CAMERA_KEY* node;
-
// Fix the up vector
Vector upvec(0,0,1), frontvec(ex-tx, ey-ty, ez-tz), sidevec;
frontvec.Normalize();
@@ -199,31 +149,15 @@ Camera::Camera (float ex, float ey, float ez, float tx, float ty, float tz, Came
upvec.Normalize();
Initialize();
- m_pAnimationKeys = AddNode (NULL, 1, CK_EYE);
- m_pAnimationKeys->param[0] = ex;
- m_pAnimationKeys->param[1] = ey;
- m_pAnimationKeys->param[2] = ez;
- node = AddNode (m_pAnimationKeys, 1, CK_TARGET);
- node->param[0] = tx;
- node->param[1] = ty;
- node->param[2] = tz;
- node = AddNode (node, 1, CK_UP);
- node->param[0] = upvec.X();
- node->param[1] = upvec.Y();
- node->param[2] = upvec.Z();
-
- m_pInstructionKeys = AddNode (NULL, 1, CK_EYE);
- m_pInstructionKeys->param[0] = ex;
- m_pInstructionKeys->param[1] = ey;
- m_pInstructionKeys->param[2] = ez;
- node = AddNode (m_pInstructionKeys, 1, CK_TARGET);
- node->param[0] = tx;
- node->param[1] = ty;
- node->param[2] = tz;
- node = AddNode (node, 1, CK_UP);
- node->param[0] = upvec.X();
- node->param[1] = upvec.Y();
- node->param[2] = upvec.Z();
+
+ float eye[3] = { ex, ey, ez }, target[3] = { tx, ty, tz };
+
+ ChangeKey (1, false, true, eye, LC_CK_EYE);
+ ChangeKey (1, false, true, target, LC_CK_TARGET);
+ ChangeKey (1, false, true, upvec, LC_CK_UP);
+ ChangeKey (1, true, true, eye, LC_CK_EYE);
+ ChangeKey (1, true, true, target, LC_CK_TARGET);
+ ChangeKey (1, true, true, upvec, LC_CK_UP);
int i, max = 0;
@@ -252,7 +186,7 @@ Camera::~Camera()
{
if (m_nList != 0)
glDeleteLists (m_nList, 1);
- RemoveKeys ();
+
delete m_pTarget;
}
@@ -264,8 +198,6 @@ void Camera::Initialize()
m_pNext = NULL;
m_nState = 0;
- m_pAnimationKeys = NULL;
- m_pInstructionKeys = NULL;
m_nList = 0;
m_nType = LC_CAMERA_USER;
@@ -273,97 +205,109 @@ void Camera::Initialize()
for (unsigned char i = 0 ; i < sizeof(m_strName) ; i++ )
m_strName[i] = 0;
+ float *values[] = { m_fEye, m_fTarget, m_fUp };
+ RegisterKeys (values, camera_key_info, LC_CK_COUNT);
+
m_pTarget = new CameraTarget (this);
}
/////////////////////////////////////////////////////////////////////////////
// Camera save/load
-void Camera::FileLoad(File* file)
+bool Camera::FileLoad(File& file)
{
- RemoveKeys();
unsigned char version, ch;
- LC_CAMERA_KEY *node;
- file->Read(&version, 1);
+ file.ReadByte (&version, 1);
+
+ if (version > LC_CAMERA_SAVE_VERSION)
+ return false;
+
+ if (version > 5)
+ if (!Object::FileLoad (file))
+ return false;
if (version == 4)
{
- file->Read(m_strName, 80);
+ file.Read(m_strName, 80);
m_strName[80] = 0;
}
else
{
- file->Read(&ch, 1);
+ file.Read(&ch, 1);
if (ch == 0xFF)
- return; // don't read CString
- file->Read(m_strName, ch);
+ return false; // don't read CString
+ file.Read(m_strName, ch);
m_strName[ch] = 0;
}
if (version < 3)
{
double d[3];
- file->Read(d, sizeof(d));
- m_pInstructionKeys = AddNode(NULL, 1, CK_EYE);
- m_pInstructionKeys->param[0] = (float)d[0];
- m_pInstructionKeys->param[1] = (float)d[1];
- m_pInstructionKeys->param[2] = (float)d[2];
- file->Read(d, sizeof(d));
- node = AddNode(m_pInstructionKeys, 1, CK_TARGET);
- node->param[0] = (float)d[0];
- node->param[1] = (float)d[1];
- node->param[2] = (float)d[2];
- file->Read (d, sizeof(d));
- node = AddNode(node, 1, CK_UP);
- node->param[0] = (float)d[0];
- node->param[1] = (float)d[1];
- node->param[2] = (float)d[2];
-// m_Start.snapshot = FALSE;
+ float f[3];
+
+ file.Read(d, sizeof(d));
+ f[0] = (float)d[0];
+ f[1] = (float)d[1];
+ f[2] = (float)d[2];
+ ChangeKey (1, false, true, f, LC_CK_EYE);
+ ChangeKey (1, true, true, f, LC_CK_EYE);
+
+ file.Read(d, sizeof(d));
+ f[0] = (float)d[0];
+ f[1] = (float)d[1];
+ f[2] = (float)d[2];
+ ChangeKey (1, false, true, f, LC_CK_TARGET);
+ ChangeKey (1, true, true, f, LC_CK_TARGET);
+
+ file.Read(d, sizeof(d));
+ f[0] = (float)d[0];
+ f[1] = (float)d[1];
+ f[2] = (float)d[2];
+ ChangeKey (1, false, true, f, LC_CK_UP);
+ ChangeKey (1, true, true, f, LC_CK_UP);
}
if (version == 3)
{
- file->Read(&ch, 1);
+ file.Read(&ch, 1);
- node = NULL;
while (ch--)
{
- if (node == NULL)
- {
- m_pInstructionKeys = AddNode(NULL, 1, CK_EYE);
- node = m_pInstructionKeys;
- }
- else
- node = AddNode(node, 1, CK_EYE);
-
unsigned char step;
double eye[3], target[3], up[3];
- file->Read(eye, sizeof(double[3]));
- file->Read(target, sizeof(double[3]));
- file->Read(up, sizeof(double[3]));
- file->Read(&step, 1);
+ float f[3];
+
+ file.Read(eye, sizeof(double[3]));
+ file.Read(target, sizeof(double[3]));
+ file.Read(up, sizeof(double[3]));
+ file.Read(&step, 1);
if (up[0] == 0 && up[1] == 0 && up[2] == 0)
up[2] = 1;
- node->time = step;
- node->param[0] = (float)eye[0];
- node->param[1] = (float)eye[1];
- node->param[2] = (float)eye[2];
- node = AddNode(node, step, CK_TARGET);
- node->param[0] = (float)target[0];
- node->param[1] = (float)target[1];
- node->param[2] = (float)target[2];
- node = AddNode(node, step, CK_UP);
- node->param[0] = (float)up[0];
- node->param[1] = (float)up[1];
- node->param[2] = (float)up[2];
+ f[0] = (float)eye[0];
+ f[1] = (float)eye[1];
+ f[2] = (float)eye[2];
+ ChangeKey (step, false, true, f, LC_CK_EYE);
+ ChangeKey (step, true, true, f, LC_CK_EYE);
+
+ f[0] = (float)target[0];
+ f[1] = (float)target[1];
+ f[2] = (float)target[2];
+ ChangeKey (step, false, true, f, LC_CK_TARGET);
+ ChangeKey (step, true, true, f, LC_CK_TARGET);
+
+ f[0] = (float)up[0];
+ f[1] = (float)up[1];
+ f[2] = (float)up[2];
+ ChangeKey (step, false, true, f, LC_CK_UP);
+ ChangeKey (step, true, true, f, LC_CK_UP);
int snapshot; // BOOL under Windows
int cam;
- file->Read(&snapshot, 4);
- file->Read(&cam, 4);
+ file.Read(&snapshot, 4);
+ file.Read(&cam, 4);
// if (cam == -1)
// node->pCam = NULL;
// else
@@ -373,66 +317,56 @@ void Camera::FileLoad(File* file)
if (version < 4)
{
- m_pAnimationKeys = AddNode (NULL, 1, CK_EYE);
- LC_CAMERA_KEY* node = AddNode (m_pAnimationKeys, 1, CK_TARGET);
- node = AddNode (node, 1, CK_UP);
- memcpy(m_pAnimationKeys->param, m_pInstructionKeys->param, sizeof(float[3]));
- memcpy(m_pAnimationKeys->next->param, m_pInstructionKeys->next->param, sizeof(float[3]));
- memcpy(node->param, m_pInstructionKeys->next->next->param, sizeof(float[3]));
-
double d;
- file->Read(&d, sizeof(d)); m_fovy = (float)d;
- file->Read(&d, sizeof(d)); m_zFar = (float)d;
- file->Read(&d, sizeof(d)); m_zNear= (float)d;
+ file.Read(&d, sizeof(d)); m_fovy = (float)d;
+ file.Read(&d, sizeof(d)); m_zFar = (float)d;
+ file.Read(&d, sizeof(d)); m_zNear= (float)d;
}
else
{
int n;
- file->Read(&n, 4);
- for (node = NULL; n--;)
+ if (version < 6)
{
- if (node == NULL)
+ unsigned short time;
+ float param[4];
+ unsigned char type;
+
+ file.Read(&n, 4);
+ while (n--)
{
- m_pInstructionKeys = AddNode(NULL, 1, CK_EYE);
- node = m_pInstructionKeys;
+ file.Read(&time, 2);
+ file.Read(param, 12);
+ file.Read(&type, 1);
+
+ ChangeKey (time, false, true, param, type);
}
- else
- node = AddNode(node, 1, CK_EYE);
- file->Read(&node->time, 2);
- file->Read(node->param, 12);
- file->Read(&node->type, 1);
- }
- file->Read(&n, 4);
- for (node = NULL; n--;)
- {
- if (node == NULL)
+ file.Read(&n, 4);
+ while (n--)
{
- m_pAnimationKeys = AddNode(NULL, 1, CK_EYE);
- node = m_pAnimationKeys;
+ file.Read(&time, 2);
+ file.Read(param, 12);
+ file.Read(&type, 1);
+
+ ChangeKey (time, true, true, param, type);
}
- else
- node = AddNode(node, 1, CK_EYE);
- file->Read(&node->time, 2);
- file->Read(node->param, 12);
- file->Read(&node->type, 1);
}
- file->Read(&m_fovy, 4);
- file->Read(&m_zFar, 4);
- file->Read(&m_zNear, 4);
+ file.Read(&m_fovy, 4);
+ file.Read(&m_zFar, 4);
+ file.Read(&m_zNear, 4);
if (version < 5)
{
- file->Read(&n, 4);
+ file.Read(&n, 4);
if (n != 0)
m_nState |= LC_CAMERA_HIDDEN;
}
else
{
- file->Read(&m_nState, 1);
- file->Read(&m_nType, 1);
+ file.Read(&m_nState, 1);
+ file.Read(&m_nType, 1);
}
}
@@ -441,94 +375,39 @@ void Camera::FileLoad(File* file)
unsigned long show;
int user;
- file->Read(&show, 4);
+ file.Read(&show, 4);
// if (version > 2)
- file->Read(&user, 4);
+ file.Read(&user, 4);
if (show == 0)
m_nState |= LC_CAMERA_HIDDEN;
}
+
+ return true;
}
-void Camera::FileSave(File* file)
+void Camera::FileSave(File& file)
{
- int n;
- LC_CAMERA_KEY *node;
- unsigned char ch = 5; // LeoCAD 0.70
-
- file->Write(&ch, 1);
- ch = (unsigned char)strlen(m_strName);
- file->Write(&ch, 1);
- file->Write(m_strName, ch);
+ unsigned char ch = LC_CAMERA_SAVE_VERSION;
- for (n = 0, node = m_pInstructionKeys; node; node = node->next)
- n++;
- file->Write(&n, 4);
-
- for (node = m_pInstructionKeys; node; node = node->next)
- {
- file->Write(&node->time, 2);
- file->Write(node->param, 12);
- file->Write(&node->type, 1);
- }
+ file.WriteByte (&ch, 1);
- for (n = 0, node = m_pAnimationKeys; node; node = node->next)
- n++;
- file->Write(&n, 4);
+ Object::FileSave (file);
- for (node = m_pAnimationKeys; node; node = node->next)
- {
- file->Write(&node->time, 2);
- file->Write(node->param, 12);
- file->Write(&node->type, 1);
- }
+ ch = (unsigned char)strlen(m_strName);
+ file.Write(&ch, 1);
+ file.Write(m_strName, ch);
- file->Write(&m_fovy, 4);
- file->Write(&m_zFar, 4);
- file->Write(&m_zNear, 4);
+ file.Write(&m_fovy, 4);
+ file.Write(&m_zFar, 4);
+ file.Write(&m_zNear, 4);
// version 5
- file->Write(&m_nState, 1);
- file->Write(&m_nType, 1);
+ file.Write(&m_nState, 1);
+ file.Write(&m_nType, 1);
}
/////////////////////////////////////////////////////////////////////////////
// Camera operations
-void Camera::ChangeKey (unsigned short nTime, bool bAnimation, bool bAddKey, float param[3], unsigned char nKeyType)
-{
- LC_CAMERA_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;
-
- newpos->param[0] = param[0];
- newpos->param[1] = param[1];
- newpos->param[2] = param[2];
-}
-
void Camera::Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz)
{
if (IsSide())
@@ -540,8 +419,8 @@ void Camera::Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx
m_fTarget[1] += dy;
m_fTarget[2] += dz;
- ChangeKey(nTime, bAnimation, bAddKey, m_fEye, CK_EYE);
- ChangeKey(nTime, bAnimation, bAddKey, m_fTarget, CK_TARGET);
+ ChangeKey(nTime, bAnimation, bAddKey, m_fEye, LC_CK_EYE);
+ ChangeKey(nTime, bAnimation, bAddKey, m_fTarget, LC_CK_TARGET);
}
else
{
@@ -551,7 +430,7 @@ void Camera::Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx
m_fEye[1] += dy;
m_fEye[2] += dz;
- ChangeKey(nTime, bAnimation, bAddKey, m_fEye, CK_EYE);
+ ChangeKey(nTime, bAnimation, bAddKey, m_fEye, LC_CK_EYE);
}
if (IsTargetSelected())
@@ -560,7 +439,7 @@ void Camera::Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx
m_fTarget[1] += dy;
m_fTarget[2] += dz;
- ChangeKey(nTime, bAnimation, bAddKey, m_fTarget, CK_TARGET);
+ ChangeKey(nTime, bAnimation, bAddKey, m_fTarget, LC_CK_TARGET);
}
// Fix the up vector
@@ -571,105 +450,23 @@ void Camera::Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx
upvec.Normalize();
upvec.ToFloat(m_fUp);
- ChangeKey(nTime, bAnimation, bAddKey, m_fUp, CK_UP);
- }
-}
-
-void Camera::RemoveKeys()
-{
- LC_CAMERA_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);
+ ChangeKey(nTime, bAnimation, bAddKey, m_fUp, LC_CK_UP);
}
}
-void Camera::CalculatePosition (unsigned short nTime, bool bAnimation, float eye[3], float target[3], float up[3])
+void Camera::UpdatePosition (unsigned short nTime, bool bAnimation)
{
- LC_CAMERA_KEY *node, *pe = NULL, *ne = NULL, *pt = NULL, *nt = NULL, *pu = NULL, *nu = NULL;
- if (bAnimation)
- node = m_pAnimationKeys;
- else
- node = m_pInstructionKeys;
-
- while (node && (!ne || !nt || !nu))
- {
- if (node->time <= nTime)
- {
- switch (node->type)
- {
- case CK_EYE: pe = node; break;
- case CK_TARGET: pt = node; break;
- case CK_UP: pu = node; break;
- }
- }
- else
- {
- switch (node->type)
- {
- case CK_EYE: if (ne == NULL) ne = node; break;
- case CK_TARGET: if (nt == NULL) nt = node; break;
- case CK_UP: if (nu == NULL) nu = node; break;
- }
- }
-
- node = node->next;
- }
-
- // TODO: USE KEY IN/OUT WEIGHTS
- if (bAnimation && (ne != NULL) && (pe->time != nTime))
- {
- float t = (float)(nTime - pe->time)/(ne->time - pe->time);
- eye[0] = pe->param[0] + (ne->param[0] - pe->param[0])*t;
- eye[1] = pe->param[1] + (ne->param[1] - pe->param[1])*t;
- eye[2] = pe->param[2] + (ne->param[2] - pe->param[2])*t;
- }
- else
- memcpy (eye, pe->param, sizeof(float[3]));
-
- if (bAnimation && (nt != NULL) && (pt->time != nTime))
- {
- float t = (float)(nTime - pt->time)/(nt->time - pt->time);
- target[0] = pt->param[0] + (nt->param[0] - pt->param[0])*t;
- target[1] = pt->param[1] + (nt->param[1] - pt->param[1])*t;
- target[2] = pt->param[2] + (nt->param[2] - pt->param[2])*t;
- }
- else
- memcpy (target, pt->param, sizeof(float[3]));
-
- if (bAnimation && (nu != NULL) && (pu->time != nTime))
- {
- float t = (float)(nTime - pu->time)/(nu->time - pu->time);
- up[0] = pu->param[0] + (nu->param[0] - pu->param[0])*t;
- up[1] = pu->param[1] + (nu->param[1] - pu->param[1])*t;
- up[2] = pu->param[2] + (nu->param[2] - pu->param[2])*t;
- }
- else
- memcpy (up, pu->param, sizeof(float[3]));
+ CalculateKeys (nTime, bAnimation);
// Fix the up vector
- Vector upvec(up), frontvec(eye[0]-target[0], eye[1]-target[1], eye[2]-target[2]), sidevec;
+ Vector frontvec(m_fEye[0]-m_fTarget[0], m_fEye[1]-m_fTarget[1], m_fEye[2]-m_fTarget[2]);
+ Vector upvec(m_fUp), sidevec;
+
sidevec.Cross(frontvec, upvec);
upvec.Cross(sidevec, frontvec);
upvec.Normalize();
- upvec.ToFloat(up);
-}
-
-void Camera::UpdatePosition (unsigned short nTime, bool bAnimation)
-{
- CalculatePosition(nTime, bAnimation, m_fEye, m_fTarget, m_fUp);
+ upvec.ToFloat(m_fUp);
- Vector frontvec (m_fTarget[0]-m_fEye[0], m_fTarget[1]-m_fEye[1], m_fTarget[2]-m_fEye[2]);
float len = frontvec.Length();
Matrix mat;
@@ -723,10 +520,10 @@ void Camera::UpdatePosition (unsigned short nTime, bool bAnimation)
glEndList();
- if (_nTargetList == 0)
+ if (m_nTargetList == 0)
{
- _nTargetList = glGenLists(1);
- glNewList(_nTargetList, GL_COMPILE);
+ m_nTargetList = glGenLists(1);
+ glNewList (m_nTargetList, GL_COMPILE);
glEnableClientState(GL_VERTEX_ARRAY);
float box[24][3] = {
@@ -768,13 +565,13 @@ void Camera::Render(float fLineWidth)
{
glLineWidth(fLineWidth*2);
glColor3ubv(FlatColorArray[(m_nState & LC_CAMERA_TARGET_FOCUSED) != 0 ? LC_COL_FOCUSED : LC_COL_SELECTED]);
- glCallList(_nTargetList);
+ glCallList(m_nTargetList);
glLineWidth(fLineWidth);
}
else
{
glColor3f(0.5f, 0.8f, 0.5f);
- glCallList(_nTargetList);
+ glCallList(m_nTargetList);
}
glColor3f(0.5f, 0.8f, 0.5f);
@@ -878,8 +675,8 @@ void Camera::DoZoom(int dy, int mouse, unsigned short nTime, bool bAnimation, bo
m_fTarget[1] += frontvec.Y();
m_fTarget[2] += frontvec.Z();
- ChangeKey(nTime, bAnimation, bAddKey, m_fEye, CK_EYE);
- ChangeKey(nTime, bAnimation, bAddKey, m_fTarget, CK_TARGET);
+ ChangeKey(nTime, bAnimation, bAddKey, m_fEye, LC_CK_EYE);
+ ChangeKey(nTime, bAnimation, bAddKey, m_fTarget, LC_CK_TARGET);
UpdatePosition(nTime, bAnimation);
}
@@ -899,8 +696,8 @@ void Camera::DoPan(int dx, int dy, int mouse, unsigned short nTime, bool bAnimat
m_fTarget[1] += upvec.Y() + sidevec.Y();
m_fTarget[2] += upvec.Z() + sidevec.Z();
- ChangeKey(nTime, bAnimation, bAddKey, m_fEye, CK_EYE);
- ChangeKey(nTime, bAnimation, bAddKey, m_fTarget, CK_TARGET);
+ ChangeKey(nTime, bAnimation, bAddKey, m_fEye, LC_CK_EYE);
+ ChangeKey(nTime, bAnimation, bAddKey, m_fTarget, LC_CK_TARGET);
UpdatePosition(nTime, bAnimation);
}
@@ -929,8 +726,8 @@ void Camera::DoRotate(int dx, int dy, int mouse, unsigned short nTime, bool bAni
upvec.Normalize();
upvec.ToFloat(m_fUp);
- ChangeKey(nTime, bAnimation, bAddKey, m_fEye, CK_EYE);
- ChangeKey(nTime, bAnimation, bAddKey, m_fUp, CK_UP);
+ ChangeKey(nTime, bAnimation, bAddKey, m_fEye, LC_CK_EYE);
+ ChangeKey(nTime, bAnimation, bAddKey, m_fUp, LC_CK_UP);
UpdatePosition(nTime, bAnimation);
}
@@ -942,7 +739,7 @@ void Camera::DoRoll(int dx, int mouse, unsigned short nTime, bool bAnimation, bo
mat.FromAxisAngle(front, 2.0f*dx/(21-mouse));
mat.TransformPoints(m_fUp, 1);
- ChangeKey(nTime, bAnimation, bAddKey, m_fUp, CK_UP);
+ ChangeKey(nTime, bAnimation, bAddKey, m_fUp, LC_CK_UP);
UpdatePosition(nTime, bAnimation);
}
diff --git a/common/camera.h b/common/camera.h
index 2f4acde..75e319c 100644
--- a/common/camera.h
+++ b/common/camera.h
@@ -23,15 +23,13 @@ typedef enum
LC_CAMERA_MAIN, LC_CAMERA_USER
} LC_CAMERA_TYPES;
-typedef enum { CK_EYE, CK_TARGET, CK_UP } CK_TYPES;
-
-typedef struct LC_CAMERA_KEY
+typedef enum
{
- unsigned short time;
- float param[3];
- unsigned char type;
- LC_CAMERA_KEY* next;
-} LC_CAMERA_KEY;
+ LC_CK_EYE,
+ LC_CK_TARGET,
+ LC_CK_UP,
+ LC_CK_COUNT
+} LC_CK_TYPES;
class CameraTarget : public Object
{
@@ -115,14 +113,14 @@ public:
void FocusTarget()
{ m_nState |= (LC_CAMERA_TARGET_FOCUSED|LC_CAMERA_TARGET_SELECTED); }
-public:
+ public:
+ bool FileLoad (File& file);
+ void FileSave (File& file);
+
void MinIntersectDist (LC_CLICKLINE* pLine);
- void ChangeKey(unsigned short nTime, bool bAnimation, bool bAddKey, float param[3], unsigned char nKeyType);
void UpdatePosition(unsigned short nTime, bool bAnimation);
void Render(float fLineWidth);
void LoadProjection(float fAspect);
- void FileLoad(File* file);
- void FileSave(File* file);
void DoZoom(int dy, int mouse, unsigned short nTime, bool bAnimation, bool bAddKey);
void DoPan(int dx, int dy, int mouse, unsigned short nTime, bool bAnimation, bool bAddKey);
@@ -139,27 +137,23 @@ public:
float m_zFar;
protected:
- void CalculatePosition(unsigned short nTime, bool bAnimation, float eye[3], float target[3], float up[3]);
- void RemoveKeys();
void Initialize();
// Camera target
CameraTarget* m_pTarget;
- // Position
- LC_CAMERA_KEY* m_pAnimationKeys;
- LC_CAMERA_KEY* m_pInstructionKeys;
-
// Attributes
char m_strName[81];
unsigned char m_nState;
unsigned char m_nType;
GLuint m_nList;
+ static GLuint m_nTargetList;
// Temporary position
float m_fEye[3];
float m_fTarget[3];
float m_fUp[3];
+
TiledRender* m_pTR;
};
diff --git a/common/light.cpp b/common/light.cpp
index 79438e7..12d5cc6 100644
--- a/common/light.cpp
+++ b/common/light.cpp
@@ -11,27 +11,19 @@
GLuint Light::m_nSphereList = 0;
GLuint Light::m_nTargetList = 0;
-// =============================================================================
-// Static functions
-
-static LC_LIGHT_KEY* AddNode (LC_LIGHT_KEY *node, unsigned short nTime, unsigned char nType)
+static LC_OBJECT_KEY_INFO light_key_info[LC_LK_COUNT] =
{
- LC_LIGHT_KEY* newnode = (LC_LIGHT_KEY*)malloc (sizeof (LC_LIGHT_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] = 0;
-
- return newnode;
-}
+ { "Light Position", 3, LC_LK_POSITION },
+ { "Light Target", 3, LC_LK_TARGET },
+ { "Ambient Color", 3, LC_LK_AMBIENT },
+ { "Diffuse Color", 3, LC_LK_DIFFUSE },
+ { "Specular Color", 3, LC_LK_SPECULAR },
+ { "Constant Attenuation", 1, LC_LK_CONSTANT },
+ { "Linear Attenuation", 1, LC_LK_LINEAR },
+ { "Quadratic Attenuation", 1, LC_LK_QUADRATIC },
+ { "Spot Cutoff", 1, LC_LK_CUTOFF },
+ { "Spot Exponent", 1, LC_LK_EXPONENT }
+};
// =============================================================================
// CameraTarget class
@@ -65,67 +57,36 @@ void LightTarget::MinIntersectDist (LC_CLICKLINE* pLine)
// =============================================================================
// Light class
+// New positional light
Light::Light (float px, float py, float pz)
: Object (LC_OBJECT_LIGHT)
{
- LC_LIGHT_KEY *node;
-
Initialize ();
- m_pAnimationKeys = node = AddNode (NULL, 1, LK_POSITION);
- node->param[0] = px;
- node->param[1] = py;
- node->param[2] = pz;
- node = AddNode (node, 1, LK_COLOR);
- node->param[0] = 1.0f;
- node->param[1] = 1.0f;
- node->param[2] = 1.0f;
-
- m_pInstructionKeys = node = AddNode (NULL, 1, LK_POSITION);
- node->param[0] = px;
- node->param[1] = py;
- node->param[2] = pz;
- node = AddNode (node, 1, LK_COLOR);
- node->param[0] = 1.0f;
- node->param[1] = 1.0f;
- node->param[2] = 1.0f;
+ float pos[] = { px, py, pz }, target[] = { 0, 0, 0 };
+
+ ChangeKey (1, false, true, pos, LC_LK_POSITION);
+ ChangeKey (1, false, true, target, LC_LK_TARGET);
+ ChangeKey (1, true, true, pos, LC_LK_POSITION);
+ ChangeKey (1, true, true, target, LC_LK_TARGET);
m_fPos[3] = 0.0f;
+
UpdatePosition (1, false);
}
+// New directional light
Light::Light (float px, float py, float pz, float tx, float ty, float tz)
: Object (LC_OBJECT_LIGHT)
{
- LC_LIGHT_KEY *node;
-
Initialize ();
- m_pAnimationKeys = node = AddNode (NULL, 1, LK_POSITION);
- node->param[0] = px;
- node->param[1] = py;
- node->param[2] = pz;
- node = AddNode (node, 1, LK_TARGET);
- node->param[0] = tx;
- node->param[1] = ty;
- node->param[2] = tz;
- node = AddNode (node, 1, LK_COLOR);
- node->param[0] = 1.0f;
- node->param[1] = 1.0f;
- node->param[2] = 1.0f;
-
- m_pInstructionKeys = node = AddNode (NULL, 1, LK_POSITION);
- node->param[0] = px;
- node->param[1] = py;
- node->param[2] = pz;
- node = AddNode (node, 1, LK_TARGET);
- node->param[0] = tx;
- node->param[1] = ty;
- node->param[2] = tz;
- node = AddNode (node, 1, LK_COLOR);
- node->param[0] = 1.0f;
- node->param[1] = 1.0f;
- node->param[2] = 1.0f;
+ float pos[] = { px, py, pz }, target[] = { tx, ty, tz };
+
+ ChangeKey (1, false, true, pos, LC_LK_POSITION);
+ ChangeKey (1, false, true, target, LC_LK_TARGET);
+ ChangeKey (1, true, true, pos, LC_LK_POSITION);
+ ChangeKey (1, true, true, target, LC_LK_TARGET);
m_pTarget = new LightTarget (this);
m_fPos[3] = 1.0f;
@@ -138,39 +99,46 @@ void Light::Initialize ()
m_bEnabled = true;
m_pNext = NULL;
m_nState = 0;
- m_pAnimationKeys = NULL;
- m_pInstructionKeys = NULL;
m_pTarget = NULL;
m_nList = 0;
memset (m_strName, 0, sizeof (m_strName));
- m_fColor[3] = 1.0f;
+
+ m_fAmbient[3] = 1.0f;
+ m_fDiffuse[3] = 1.0f;
+ m_fSpecular[3] = 1.0f;
+
+ float *values[] = { m_fPos, m_fTarget, m_fAmbient, m_fDiffuse, m_fSpecular,
+ &m_fConstant, &m_fLinear, &m_fQuadratic, &m_fCutoff, &m_fExponent };
+ RegisterKeys (values, light_key_info, LC_LK_COUNT);
+
+ // set the default values
+ float ambient[] = { 0, 0, 0 }, diffuse[] = { 0.8f, 0.8f, 0.8f }, specular[] = { 1, 1, 1 };
+ float constant = 1, linear = 0, quadratic = 0, cutoff = 30, exponent = 0;
+
+ ChangeKey (1, false, true, ambient, LC_LK_AMBIENT);
+ ChangeKey (1, false, true, diffuse, LC_LK_DIFFUSE);
+ ChangeKey (1, false, true, specular, LC_LK_SPECULAR);
+ ChangeKey (1, false, true, &constant, LC_LK_CONSTANT);
+ ChangeKey (1, false, true, &linear, LC_LK_LINEAR);
+ ChangeKey (1, false, true, &quadratic, LC_LK_QUADRATIC);
+ ChangeKey (1, false, true, &cutoff, LC_LK_CUTOFF);
+ ChangeKey (1, false, true, &exponent, LC_LK_EXPONENT);
+ ChangeKey (1, true, true, ambient, LC_LK_AMBIENT);
+ ChangeKey (1, true, true, diffuse, LC_LK_DIFFUSE);
+ ChangeKey (1, true, true, specular, LC_LK_SPECULAR);
+ ChangeKey (1, true, true, &constant, LC_LK_CONSTANT);
+ ChangeKey (1, true, true, &linear, LC_LK_LINEAR);
+ ChangeKey (1, true, true, &quadratic, LC_LK_QUADRATIC);
+ ChangeKey (1, true, true, &cutoff, LC_LK_CUTOFF);
+ ChangeKey (1, true, true, &exponent, LC_LK_EXPONENT);
}
Light::~Light ()
{
if (m_nList != 0)
glDeleteLists (m_nList, 1);
- RemoveKeys ();
- delete m_pTarget;
-}
-
-void Light::RemoveKeys ()
-{
- LC_LIGHT_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);
- }
+ delete m_pTarget;
}
void Light::MinIntersectDist (LC_CLICKLINE* pLine)
@@ -191,42 +159,6 @@ void Light::MinIntersectDist (LC_CLICKLINE* pLine)
m_pTarget->MinIntersectDist (pLine);
}
-void Light::ChangeKey (unsigned short nTime, bool bAnimation, bool bAddKey, float param[3], unsigned char nKeyType)
-{
- LC_LIGHT_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;
-
- newpos->param[0] = param[0];
- newpos->param[1] = param[1];
- newpos->param[2] = param[2];
-}
-
void Light::Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz)
{
if (IsEyeSelected())
@@ -235,7 +167,7 @@ void Light::Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx,
m_fPos[1] += dy;
m_fPos[2] += dz;
- ChangeKey (nTime, bAnimation, bAddKey, m_fPos, LK_POSITION);
+ ChangeKey (nTime, bAnimation, bAddKey, m_fPos, LC_LK_POSITION);
}
if (IsTargetSelected())
@@ -244,80 +176,13 @@ void Light::Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx,
m_fTarget[1] += dy;
m_fTarget[2] += dz;
- ChangeKey (nTime, bAnimation, bAddKey, m_fTarget, LK_TARGET);
- }
-}
-
-void Light::CalculatePosition (unsigned short nTime, bool bAnimation, float pos[3], float target[3], float color[3])
-{
- LC_LIGHT_KEY *node, *pp = NULL, *np = NULL, *pt = NULL, *nt = NULL, *pc = NULL, *nc = NULL;
- if (bAnimation)
- node = m_pAnimationKeys;
- else
- node = m_pInstructionKeys;
-
- while (node && (!np || !nt || !nc))
- {
- if (node->time <= nTime)
- {
- switch (node->type)
- {
- case LK_POSITION: pp = node; break;
- case LK_TARGET: pt = node; break;
- case LK_COLOR: pc = node; break;
- }
- }
- else
- {
- switch (node->type)
- {
- case LK_POSITION: if (np == NULL) np = node; break;
- case LK_TARGET: if (nt == NULL) nt = node; break;
- case LK_COLOR: if (nc == NULL) nc = node; break;
- }
- }
-
- node = node->next;
- }
-
- // TODO: USE KEY IN/OUT WEIGHTS
- if (bAnimation && (np != NULL) && (pp->time != nTime))
- {
- float t = (float)(nTime - pp->time)/(np->time - pp->time);
- pos[0] = pp->param[0] + (np->param[0] - pp->param[0])*t;
- pos[1] = pp->param[1] + (np->param[1] - pp->param[1])*t;
- pos[2] = pp->param[2] + (np->param[2] - pp->param[2])*t;
- }
- else
- memcpy (pos, pp->param, sizeof(float[3]));
-
- if (m_pTarget != NULL)
- {
- if (bAnimation && (nt != NULL) && (pt->time != nTime))
- {
- float t = (float)(nTime - pt->time)/(nt->time - pt->time);
- target[0] = pt->param[0] + (nt->param[0] - pt->param[0])*t;
- target[1] = pt->param[1] + (nt->param[1] - pt->param[1])*t;
- target[2] = pt->param[2] + (nt->param[2] - pt->param[2])*t;
- }
- else
- memcpy (target, pt->param, sizeof(float[3]));
+ ChangeKey (nTime, bAnimation, bAddKey, m_fTarget, LC_LK_TARGET);
}
-
- if (bAnimation && (nc != NULL) && (pc->time != nTime))
- {
- float t = (float)(nTime - pc->time)/(nc->time - pc->time);
- color[0] = pc->param[0] + (nc->param[0] - pc->param[0])*t;
- color[1] = pc->param[1] + (nc->param[1] - pc->param[1])*t;
- color[2] = pc->param[2] + (nc->param[2] - pc->param[2])*t;
- }
- else
- memcpy (color, pc->param, sizeof(float[3]));
}
void Light::UpdatePosition (unsigned short nTime, bool bAnimation)
{
- CalculatePosition (nTime, bAnimation, m_fPos, m_fTarget, m_fColor);
+ CalculateKeys (nTime, bAnimation);
BoundingBoxCalculate (m_fPos);
if (m_pTarget != NULL)
@@ -538,7 +403,7 @@ void Light::Render (float fLineWidth)
modelview.Invert ();
glMultMatrixf (modelview.m);
- projection.CreatePerspective (90.0f, 1.0f, 0.01, len);
+ projection.CreatePerspective (2*m_fCutoff, 1.0f, 0.01, len);
projection.Invert ();
glMultMatrixf (projection.m);
@@ -602,27 +467,22 @@ void Light::Setup (int index)
glEnable (light);
glLightfv (light, GL_POSITION, m_fPos);
- // glLightfv (light, GL_AMBIENT, m_fColor);
- // glLightfv (light, GL_DIFFUSE, m_fColor);
- // glLightfv (light, GL_SPECULAR, m_fColor);
- float amb[]={0,0,0,1};
- float diff[]={0,0,1,1};
- float spec[]={1,1,1,1};
- glLightfv (light, GL_AMBIENT, amb);
- glLightfv (light, GL_DIFFUSE, diff);
- glLightfv (light, GL_SPECULAR, spec);
+ glLightfv (light, GL_AMBIENT, m_fAmbient);
+ glLightfv (light, GL_DIFFUSE, m_fDiffuse);
+ glLightfv (light, GL_SPECULAR, m_fSpecular);
- glLightf (light, GL_CONSTANT_ATTENUATION, 1);
- glLightf (light, GL_LINEAR_ATTENUATION, 0);
- glLightf (light, GL_QUADRATIC_ATTENUATION, 0);
+ glLightf (light, GL_CONSTANT_ATTENUATION, m_fConstant);
+ glLightf (light, GL_LINEAR_ATTENUATION, m_fLinear);
+ glLightf (light, GL_QUADRATIC_ATTENUATION, m_fQuadratic);
if (m_pTarget != NULL)
{
Vector dir (m_fTarget[0]-m_fPos[0], m_fTarget[1]-m_fPos[1], m_fTarget[2]-m_fPos[2]);
dir.Normalize ();
- glLightf (light, GL_SPOT_CUTOFF, 30.0f);
+ glLightf (light, GL_SPOT_CUTOFF, m_fCutoff);
+ glLightf (light, GL_SPOT_EXPONENT, m_fExponent);
glLightfv (light, GL_SPOT_DIRECTION, dir);
}
}
diff --git a/common/light.h b/common/light.h
index f40118d..f0619c9 100644
--- a/common/light.h
+++ b/common/light.h
@@ -14,15 +14,14 @@
class Light;
class LightTarget;
-typedef enum { LK_POSITION, LK_TARGET, LK_COLOR } LK_TYPES;
-
-typedef struct LC_LIGHT_KEY
+typedef enum
{
- unsigned short time;
- float param[3];
- unsigned char type;
- LC_LIGHT_KEY* next;
-} LC_LIGHT_KEY;
+ LC_LK_POSITION, LC_LK_TARGET, // position
+ LC_LK_AMBIENT, LC_LK_DIFFUSE, LC_LK_SPECULAR, // color
+ LC_LK_CONSTANT, LC_LK_LINEAR, LC_LK_QUADRATIC, // attenuation
+ LC_LK_CUTOFF, LC_LK_EXPONENT, // spot
+ LC_LK_COUNT
+} LC_LK_TYPES;
class LightTarget : public Object
{
@@ -83,22 +82,15 @@ class Light : public Object
void Render (float fLineWidth);
void MinIntersectDist (LC_CLICKLINE* Line);
void UpdatePosition (unsigned short nTime, bool bAnimation);
- void CalculatePosition (unsigned short nTime, bool bAnimation, float pos[3], float target[3], float color[3]);
void Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz);
- void ChangeKey (unsigned short nTime, bool bAnimation, bool bAddKey, float param[3], unsigned char nKeyType);
void Setup (int index);
protected:
- void RemoveKeys ();
void Initialize ();
// Camera target
LightTarget* m_pTarget;
- // Position
- LC_LIGHT_KEY* m_pAnimationKeys;
- LC_LIGHT_KEY* m_pInstructionKeys;
-
// Attributes
float m_fCone;
unsigned char m_nState;
@@ -109,10 +101,17 @@ protected:
static GLuint m_nSphereList;
static GLuint m_nTargetList;
- // Temporary position
+ // Temporary parameters
float m_fPos[4];
- float m_fTarget[4];
- float m_fColor[4];
+ float m_fTarget[3];
+ float m_fAmbient[4];
+ float m_fDiffuse[4];
+ float m_fSpecular[4];
+ float m_fConstant;
+ float m_fLinear;
+ float m_fQuadratic;
+ float m_fCutoff;
+ float m_fExponent;
};
#endif // _LIGHT_H_
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];
}
// =============================================================================
diff --git a/common/object.h b/common/object.h
index 495ee90..202e438 100755
--- a/common/object.h
+++ b/common/object.h
@@ -10,6 +10,7 @@ class Object;
#define LC_OBJECT_SELECTED 0x02
#define LC_OBJECT_FOCUSED 0x04
*/
+
typedef enum
{
LC_OBJECT_PIECE,
@@ -22,6 +23,22 @@ typedef enum
// LC_OBJECT_CURVE
} LC_OBJECT_TYPE;
+// key handling
+typedef struct LC_OBJECT_KEY
+{
+ unsigned short time;
+ float param[4];
+ unsigned char type;
+ LC_OBJECT_KEY* next;
+} LC_OBJECT_KEY;
+
+typedef struct
+{
+ const char *description;
+ unsigned char size; // number of floats
+ unsigned char type;
+} LC_OBJECT_KEY_INFO;
+
// rendering parameters
typedef struct
{
@@ -132,11 +149,35 @@ class Object
Object* GetTopAncestor ()
{ return m_pParent ? m_pParent->GetTopAncestor () : this; }
*/
+
protected:
- // char m_strName[LC_OBJECT_NAME_LEN+1];
+ // Str m_strName;
// unsigned char m_nState;
+ virtual bool FileLoad (File& file);
+ virtual void FileSave (File& file);
+
+ // Key handling stuff
+ public:
+ void CalculateSingleKey (unsigned short nTime, bool bAnimation, int keytype, float *value);
+ void ChangeKey (unsigned short time, bool animation, bool addkey, const float *param, unsigned char keytype);
+
+ protected:
+ void RegisterKeys (float *values[], LC_OBJECT_KEY_INFO* info, int count);
+ void CalculateKeys (unsigned short nTime, bool bAnimation);
+
+ private:
+ void RemoveKeys ();
+
+ LC_OBJECT_KEY* m_pAnimationKeys;
+ LC_OBJECT_KEY* m_pInstructionKeys;
+ float **m_pKeyValues;
+
+ LC_OBJECT_KEY_INFO *m_pKeyInfo;
+ int m_nKeyInfoCount;
+
// Bounding box stuff
+ protected:
double BoundingBoxIntersectDist (LC_CLICKLINE* pLine) const;
void BoundingBoxCalculate (float pos[3]);
void BoundingBoxCalculate (Matrix *mat);
@@ -148,6 +189,8 @@ class Object
bool BoundingBoxPointInside (double x, double y, double z) const;
float m_fBoxPlanes[4][6];
+ // Object type
+ private:
LC_OBJECT_TYPE m_nObjectType;
};
diff --git a/common/piece.cpp b/common/piece.cpp
index 133ccec..c36b30a 100644
--- a/common/piece.cpp
+++ b/common/piece.cpp
@@ -13,30 +13,16 @@
#include "group.h"
#include "project.h"
-/////////////////////////////////////////////////////////////////////////////
-// Static functions
+#define LC_PIECE_SAVE_VERSION 9 // LeoCAD 0.73
-static LC_PIECE_KEY* AddNode (LC_PIECE_KEY *node, unsigned short nTime, unsigned char nType)
+static LC_OBJECT_KEY_INFO piece_key_info[LC_PK_COUNT] =
{
- LC_PIECE_KEY* newnode = (LC_PIECE_KEY*)malloc(sizeof(LC_PIECE_KEY));
-
- if (node)
- {
- newnode->next = node->next;
- node->next = newnode;
- }
- else
- newnode->next = NULL;
+ { "Position", 3, LC_PK_POSITION },
+ { "Rotation", 4, LC_PK_ROTATION }
+};
- newnode->type = nType;
- newnode->time = nTime;
- newnode->param[0] = newnode->param[1] = newnode->param[2] = newnode->param[3] = 0;
-
- if (nType == PK_ROTATION)
- newnode->param[2] = 1;
-
- return newnode;
-}
+/////////////////////////////////////////////////////////////////////////////
+// Static functions
inline static void SetCurrentColor(unsigned char nColor, bool* bTrans, bool bLighting, bool bNoAlpha)
{
@@ -111,8 +97,6 @@ Piece::Piece(PieceInfo* pPieceInfo)
m_pPieceInfo = pPieceInfo;
m_nState = 0;
m_nColor = 0;
- m_pInstructionKeys = NULL;
- m_pAnimationKeys = NULL;
m_nStepShow = 1;
m_nStepHide = 255;
m_nFrameHide = 65535;
@@ -127,7 +111,7 @@ Piece::Piece(PieceInfo* pPieceInfo)
if (m_pPieceInfo->m_nConnectionCount > 0)
{
m_pConnections = (CONNECTION*)malloc(sizeof(CONNECTION)*(m_pPieceInfo->m_nConnectionCount));
-
+
for (int i = 0; i < m_pPieceInfo->m_nConnectionCount; i++)
{
m_pConnections[i].type = m_pPieceInfo->m_pConnections[i].type;
@@ -136,17 +120,27 @@ Piece::Piece(PieceInfo* pPieceInfo)
}
}
}
+
+ float *values[] = { m_fPosition, m_fRotation };
+ RegisterKeys (values, piece_key_info, LC_PK_COUNT);
+
+ float pos[3] = { 0, 0, 0 }, rot[4] = { 0, 0, 1, 0 };
+ ChangeKey (1, false, true, pos, LC_PK_POSITION);
+ ChangeKey (1, false, true, rot, LC_PK_ROTATION);
+ ChangeKey (1, true, true, pos, LC_PK_POSITION);
+ ChangeKey (1, true, true, rot, LC_PK_ROTATION);
}
Piece::~Piece()
{
- RemoveKeys();
- if (m_pPieceInfo != NULL)
- m_pPieceInfo->DeRef();
- if (m_pDrawInfo != NULL)
- free(m_pDrawInfo);
- if (m_pConnections != NULL)
- free(m_pConnections);
+ if (m_pPieceInfo != NULL)
+ m_pPieceInfo->DeRef ();
+
+ if (m_pDrawInfo != NULL)
+ free (m_pDrawInfo);
+
+ if (m_pConnections != NULL)
+ free (m_pConnections);
}
/////////////////////////////////////////////////////////////////////////////
@@ -171,251 +165,222 @@ void Piece::SetPieceInfo(PieceInfo* pPieceInfo)
}
}
-void Piece::FileLoad(File* file, char* name)
+bool Piece::FileLoad (File& file, char* name)
{
- LC_PIECE_KEY *node;
- unsigned char version, ch;
-
- file->ReadByte(&version, 1);
+ unsigned char version, ch;
- if (version > 5)
- {
- unsigned long keys;
+ file.ReadByte (&version, 1);
- file->ReadLong(&keys, 1);
- for (node = NULL; keys--;)
- {
- if (node == NULL)
- {
- m_pInstructionKeys = AddNode(NULL, 1, PK_POSITION);
- node = m_pInstructionKeys;
- }
- else
- node = AddNode(node, 1, PK_POSITION);
+ if (version > LC_PIECE_SAVE_VERSION)
+ return false;
- file->Read(node->param, 16);
- file->ReadShort(&node->time, 1);
- file->ReadByte(&node->type, 1);
- }
-
- file->ReadLong(&keys, 1);
- for (node = NULL; keys--;)
- {
- if (node == NULL)
- {
- m_pAnimationKeys = AddNode(NULL, 1, PK_POSITION);
- node = m_pAnimationKeys;
- }
- else
- node = AddNode(node, 1, PK_POSITION);
+ if (version > 8)
+ if (!Object::FileLoad (file))
+ return false;
- file->Read(node->param, 16);
- file->ReadShort(&node->time, 1);
- file->ReadByte(&node->type, 1);
- }
- }
- else
- {
- if (version > 2)
- {
- file->Read(&ch, 1);
-
- for (node = NULL; ch--;)
- {
- if (node == NULL)
- {
- m_pInstructionKeys = AddNode(NULL, 1, PK_POSITION);
- node = m_pInstructionKeys;
- }
- else
- node = AddNode(node, 1, PK_POSITION);
-
- Matrix mat;
- if (version > 3)
- {
- float m[16];
- file->Read(m, sizeof(m));
- mat.FromFloat(m);
- }
- else
- {
- float move[3], rotate[3];
- file->Read(move, sizeof(float[3]));
- file->Read(rotate, sizeof(float[3]));
- mat.CreateOld(move[0], move[1], move[2], rotate[0], rotate[1], rotate[2]);
- }
-
- unsigned char b;
- file->ReadByte(&b, 1);
- node->time = b;
- mat.GetTranslation(&node->param[0], &node->param[1], &node->param[2]);
- node = AddNode(node, b, PK_ROTATION);
- mat.ToAxisAngle(node->param);
-
- int bl;
- file->ReadLong(&bl, 1);
- }
- }
- else
- {
- Matrix mat;
- float move[3], rotate[3];
- file->Read(move, sizeof(float[3]));
- file->Read(rotate, sizeof(float[3]));
- mat.CreateOld(move[0], move[1], move[2], rotate[0], rotate[1], rotate[2]);
-
- m_pInstructionKeys = AddNode (NULL, 1, PK_POSITION);
- mat.GetTranslation(&m_pInstructionKeys->param[0], &m_pInstructionKeys->param[1], &m_pInstructionKeys->param[2]);
- AddNode(m_pInstructionKeys, 1, PK_ROTATION);
- mat.ToAxisAngle(m_pInstructionKeys->next->param);
- }
-
- m_pAnimationKeys = AddNode (NULL, 1, PK_POSITION);
- AddNode(m_pAnimationKeys, 1, PK_ROTATION);
- memcpy(m_pAnimationKeys->param, m_pInstructionKeys->param, sizeof(float[4]));
- memcpy(m_pAnimationKeys->next->param, m_pInstructionKeys->next->param, sizeof(float[4]));
- }
-
- // Common to all versions.
- file->Read(name, 9);
- file->ReadByte(&m_nColor, 1);
-
- if (version < 5)
- {
- const unsigned char conv[20] = { 0,2,4,9,7,6,22,8,10,11,14,16,18,9,21,20,22,8,10,11 };
- m_nColor = conv[m_nColor];
- }
-
- file->ReadByte(&m_nStepShow, 1);
- if (version > 1)
- file->ReadByte(&m_nStepHide, 1);
- else
- m_nStepHide = 255;
+ if (version < 9)
+ {
+ unsigned short time;
+ float param[4];
+ unsigned char type;
+
+ if (version > 5)
+ {
+ unsigned long keys;
+
+ file.ReadLong (&keys, 1);
+ while (keys--)
+ {
+ file.Read (param, 16);
+ file.ReadShort (&time, 1);
+ file.ReadByte (&type, 1);
+
+ ChangeKey (time, false, true, param, type);
+ }
+
+ file.ReadLong (&keys, 1);
+ while (keys--)
+ {
+ file.Read (param, 16);
+ file.ReadShort (&time, 1);
+ file.ReadByte (&type, 1);
+
+ ChangeKey (time, true, true, param, type);
+ }
+ }
+ else
+ {
+ if (version > 2)
+ {
+ file.Read (&ch, 1);
+
+ while (ch--)
+ {
+ Matrix mat;
+ if (version > 3)
+ {
+ float m[16];
+ file.Read (m, sizeof(m));
+ mat.FromFloat (m);
+ }
+ else
+ {
+ float move[3], rotate[3];
+ file.Read (move, sizeof(float[3]));
+ file.Read (rotate, sizeof(float[3]));
+ mat.CreateOld (move[0], move[1], move[2], rotate[0], rotate[1], rotate[2]);
+ }
+
+ unsigned char b;
+ file.ReadByte(&b, 1);
+ time = b;
+
+ mat.GetTranslation(&param[0], &param[1], &param[2]);
+ param[3] = 0;
+ ChangeKey (time, false, true, param, LC_PK_POSITION);
+ ChangeKey (time, true, true, param, LC_PK_POSITION);
+
+ mat.ToAxisAngle (param);
+ ChangeKey (time, false, true, param, LC_PK_ROTATION);
+ ChangeKey (time, true, true, param, LC_PK_ROTATION);
+
+ int bl;
+ file.ReadLong (&bl, 1);
+ }
+ }
+ else
+ {
+ Matrix mat;
+ float move[3], rotate[3];
+ file.Read (move, sizeof(float[3]));
+ file.Read (rotate, sizeof(float[3]));
+ mat.CreateOld (move[0], move[1], move[2], rotate[0], rotate[1], rotate[2]);
+
+ mat.GetTranslation(&param[0], &param[1], &param[2]);
+ param[3] = 0;
+ ChangeKey (1, false, true, param, LC_PK_POSITION);
+ ChangeKey (1, true, true, param, LC_PK_POSITION);
+
+ mat.ToAxisAngle (param);
+ ChangeKey (1, false, true, param, LC_PK_ROTATION);
+ ChangeKey (1, true, true, param, LC_PK_ROTATION);
+ }
+ }
+ }
- if (version > 5)
- {
- file->ReadShort(&m_nFrameShow, 1);
- file->ReadShort(&m_nFrameHide, 1);
+ // Common to all versions.
+ file.Read (name, 9);
+ file.ReadByte (&m_nColor, 1);
- if (version > 7)
- {
- file->ReadByte(&m_nState, 1);
- UnSelect();
- file->ReadByte(&ch, 1);
- file->Read(m_strName, ch);
- }
- else
- {
- int hide;
- file->ReadLong(&hide, 1);
- if (hide != 0)
- m_nState |= LC_PIECE_HIDDEN;
- file->Read(m_strName, 81);
- }
+ if (version < 5)
+ {
+ const unsigned char conv[20] = { 0,2,4,9,7,6,22,8,10,11,14,16,18,9,21,20,22,8,10,11 };
+ m_nColor = conv[m_nColor];
+ }
- // 7 (0.64)
- int i = -1;
- if (version > 6)
- file->ReadLong(&i, 1);
- m_pGroup = (Group*)i;
- }
- else
- {
- m_nFrameShow = 1;
- m_nFrameHide = 65535;
+ file.ReadByte(&m_nStepShow, 1);
+ if (version > 1)
+ file.ReadByte(&m_nStepHide, 1);
+ else
+ m_nStepHide = 255;
- file->ReadByte(&ch, 1);
- if (ch == 0)
- m_pGroup = (Group*)-1;
- else
- m_pGroup = (Group*)ch;
+ if (version > 5)
+ {
+ file.ReadShort(&m_nFrameShow, 1);
+ file.ReadShort(&m_nFrameHide, 1);
+
+ if (version > 7)
+ {
+ file.ReadByte(&m_nState, 1);
+ UnSelect();
+ file.ReadByte(&ch, 1);
+ file.Read(m_strName, ch);
+ }
+ else
+ {
+ int hide;
+ file.ReadLong(&hide, 1);
+ if (hide != 0)
+ m_nState |= LC_PIECE_HIDDEN;
+ file.Read(m_strName, 81);
+ }
+
+ // 7 (0.64)
+ int i = -1;
+ if (version > 6)
+ file.ReadLong(&i, 1);
+ m_pGroup = (Group*)i;
+ }
+ else
+ {
+ m_nFrameShow = 1;
+ m_nFrameHide = 65535;
+
+ file.ReadByte(&ch, 1);
+ if (ch == 0)
+ m_pGroup = (Group*)-1;
+ else
+ m_pGroup = (Group*)ch;
+
+ file.ReadByte(&ch, 1);
+ if (ch & 0x01)
+ m_nState |= LC_PIECE_HIDDEN;
+ }
- file->ReadByte(&ch, 1);
- if (ch & 0x01)
- m_nState |= LC_PIECE_HIDDEN;
- }
+ return true;
}
-void Piece::FileSave(File* file, Group* pGroups)
+void Piece::FileSave (File& file, Group* pGroups)
{
- LC_PIECE_KEY *node;
- unsigned char ch = 8; // LeoCAD 0.70
- unsigned long n;
+ unsigned char ch = LC_PIECE_SAVE_VERSION;
- file->WriteByte(&ch, 1);
+ file.WriteByte (&ch, 1);
- for (n = 0, node = m_pInstructionKeys; node; node = node->next)
- n++;
- file->WriteLong(&n, 1);
+ Object::FileSave (file);
- for (node = m_pInstructionKeys; node; node = node->next)
- {
- file->Write(node->param, 16);
- file->WriteShort(&node->time, 1);
- 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->Write(node->param, 16);
- file->WriteShort(&node->time, 1);
- file->WriteByte(&node->type, 1);
- }
+ file.Write(m_pPieceInfo->m_strName, 9);
+ file.WriteByte(&m_nColor, 1);
+ file.WriteByte(&m_nStepShow, 1);
+ file.WriteByte(&m_nStepHide, 1);
+ file.WriteShort(&m_nFrameShow, 1);
+ file.WriteShort(&m_nFrameHide, 1);
- file->Write(m_pPieceInfo->m_strName, 9);
+ // version 8
+ file.WriteByte(&m_nState, 1);
+ ch = strlen(m_strName);
+ file.WriteByte(&ch, 1);
+ file.Write(m_strName, ch);
- file->WriteByte(&m_nColor, 1);
- file->WriteByte(&m_nStepShow, 1);
- file->WriteByte(&m_nStepHide, 1);
- file->WriteShort(&m_nFrameShow, 1);
- file->WriteShort(&m_nFrameHide, 1);
-
- // version 8
- file->WriteByte(&m_nState, 1);
- ch = strlen(m_strName);
- file->WriteByte(&ch, 1);
- file->Write(m_strName, ch);
-
- // version 7
- int i;
- if (m_pGroup != NULL)
- {
- for (i = 0; pGroups; pGroups = pGroups->m_pNext)
- {
- if (m_pGroup == pGroups)
- break;
- i++;
- }
- }
- else
- i = -1;
- file->WriteLong(&i, 1);
+ // version 7
+ int i;
+ if (m_pGroup != NULL)
+ {
+ for (i = 0; pGroups; pGroups = pGroups->m_pNext)
+ {
+ if (m_pGroup == pGroups)
+ break;
+ i++;
+ }
+ }
+ else
+ i = -1;
+ file.WriteLong(&i, 1);
}
void Piece::Initialize(float x, float y, float z, unsigned char nStep, unsigned short nFrame, unsigned char nColor)
{
- m_nFrameShow = nFrame;
- m_nStepShow = nStep;
+ m_nFrameShow = nFrame;
+ m_nStepShow = nStep;
- m_pAnimationKeys = AddNode (NULL, 1, PK_POSITION);
- AddNode(m_pAnimationKeys, 1, PK_ROTATION);
- m_pAnimationKeys->param[0] = x;
- m_pAnimationKeys->param[1] = y;
- m_pAnimationKeys->param[2] = z;
+ float pos[3] = { x, y, z }, rot[4] = { 0, 0, 1, 0 };
+ ChangeKey (1, false, true, pos, LC_PK_POSITION);
+ ChangeKey (1, false, true, rot, LC_PK_ROTATION);
+ ChangeKey (1, true, true, pos, LC_PK_POSITION);
+ ChangeKey (1, true, true, rot, LC_PK_ROTATION);
- m_pInstructionKeys = AddNode (NULL, 1, PK_POSITION);
- AddNode(m_pInstructionKeys, 1, PK_ROTATION);
- m_pInstructionKeys->param[0] = x;
- m_pInstructionKeys->param[1] = y;
- m_pInstructionKeys->param[2] = z;
+ UpdatePosition (1, false);
- UpdatePosition(1, false);
-
- m_nColor = nColor;
+ m_nColor = nColor;
}
void Piece::CreateName(Piece* pPiece)
@@ -571,71 +536,13 @@ void Piece::MinIntersectDist(LC_CLICKLINE* pLine)
free(verts);
}
-void Piece::Move(unsigned short nTime, bool bAnimation, bool bAddKey, float x, float y, float z)
-{
- m_fPosition[0] += x;
- m_fPosition[1] += y;
- m_fPosition[2] += z;
-
- ChangeKey(nTime, bAnimation, bAddKey, m_fPosition, PK_POSITION);
-}
-
-void Piece::ChangeKey(unsigned short nTime, bool bAnimation, bool bAddKey, float* param, unsigned char nKeyType)
+void Piece::Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz)
{
- LC_PIECE_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;
-
- newpos->param[0] = param[0];
- newpos->param[1] = param[1];
- newpos->param[2] = param[2];
-
- if (nKeyType == PK_ROTATION)
- newpos->param[3] = param[3];
-}
-
-void Piece::RemoveKeys()
-{
- LC_PIECE_KEY *node, *prev;
-
- for (node = m_pInstructionKeys; node;)
- {
- prev = node;
- node = node->next;
- free (prev);
- }
+ m_fPosition[0] += dx;
+ m_fPosition[1] += dy;
+ m_fPosition[2] += dz;
- for (node = m_pAnimationKeys; node;)
- {
- prev = node;
- node = node->next;
- free (prev);
- }
+ ChangeKey (nTime, bAnimation, bAddKey, m_fPosition, LC_PK_POSITION);
}
bool Piece::IsVisible(unsigned short nTime, bool bAnimation)
@@ -684,80 +591,6 @@ void Piece::CompareBoundingBox(float box[6])
}
}
-bool Piece::CalculatePositionRotation(unsigned short nTime, bool bAnimation, float pos[3], float rot[4])
-{
- LC_PIECE_KEY *node, *prevpos = NULL, *nextpos = NULL, *prevrot = NULL, *nextrot = NULL;
- if (bAnimation)
- node = m_pAnimationKeys;
- else
- node = m_pInstructionKeys;
-
- while (node && (!nextpos || !nextrot))
- {
- if (node->time <= nTime)
- {
- if (node->type == PK_POSITION)
- prevpos = node;
- else
- prevrot = node;
- }
- else
- {
- if (node->type == PK_POSITION)
- {
- if (nextpos == NULL)
- nextpos = node;
- }
- else
- {
- if (nextrot == NULL)
- nextrot = node;
- }
- }
-
- node = node->next;
- }
-
- if (bAnimation)
- {
- if ((nextpos != NULL) && (prevpos->time != nTime))
- {
- // TODO: USE KEY IN/OUT WEIGHTS
- float t = (float)(nTime - prevpos->time)/(nextpos->time - prevpos->time);
- pos[0] = prevpos->param[0] + (nextpos->param[0] - prevpos->param[0])*t;
- pos[1] = prevpos->param[1] + (nextpos->param[1] - prevpos->param[1])*t;
- pos[2] = prevpos->param[2] + (nextpos->param[2] - prevpos->param[2])*t;
- }
- else
- memcpy (pos, prevpos->param, sizeof(float[3]));
-
- if ((nextrot != NULL) && (prevrot->time != nTime))
- {
- // TODO: USE KEY IN/OUT WEIGHTS
- float t = (float)(nTime - prevrot->time)/(nextrot->time - prevrot->time);
- rot[0] = prevrot->param[0] + (nextrot->param[0] - prevrot->param[0])*t;
- rot[1] = prevrot->param[1] + (nextrot->param[1] - prevrot->param[1])*t;
- rot[2] = prevrot->param[2] + (nextrot->param[2] - prevrot->param[2])*t;
- rot[3] = prevrot->param[3] + (nextrot->param[3] - prevrot->param[3])*t;
- }
- else
- memcpy (rot, prevrot->param, sizeof(float[4]));
- }
- else
- {
- if (memcmp(pos, prevpos->param, sizeof(float[3])) ||
- memcmp(rot, prevrot->param, sizeof(float[4])))
- {
- memcpy (pos, prevpos->param, sizeof(float[3]));
- memcpy (rot, prevrot->param, sizeof(float[4]));
- }
- else
- return false;
- }
-
- return true;
-}
-
Group* Piece::GetTopGroup()
{
return m_pGroup ? m_pGroup->GetTopGroup() : NULL;
@@ -786,7 +619,7 @@ void Piece::UpdatePosition(unsigned short nTime, bool bAnimation)
if (!IsVisible(nTime, bAnimation))
m_nState &= ~(LC_PIECE_SELECTED|LC_PIECE_FOCUSED);
- CalculatePositionRotation(nTime, bAnimation, m_fPosition, m_fRotation);
+ CalculateKeys (nTime, bAnimation);
// if (CalculatePositionRotation(nTime, bAnimation, m_fPosition, m_fRotation))
{
Matrix mat(m_fRotation, m_fPosition);
diff --git a/common/piece.h b/common/piece.h
index cafa5ec..f3964fd 100644
--- a/common/piece.h
+++ b/common/piece.h
@@ -19,22 +19,17 @@ class PieceInfo;
#define LC_PIECE_SELECTED 0x02
#define LC_PIECE_FOCUSED 0x04
-typedef enum { PK_POSITION, PK_ROTATION } PK_TYPES;
-
-typedef struct LC_PIECE_KEY {
- unsigned short time;
- float param[4];
- unsigned char type;
- LC_PIECE_KEY* next;
-} LC_PIECE_KEY;
+typedef enum {
+ LC_PK_POSITION,
+ LC_PK_ROTATION,
+ LC_PK_COUNT
+} LC_PK_TYPES;
class Piece : public Object
{
-
-
public:
- Piece(PieceInfo* pPieceInfo);
- ~Piece();
+ Piece (PieceInfo* pPieceInfo);
+ ~Piece ();
Piece* m_pNext;
Piece* m_pLink;
@@ -66,14 +61,13 @@ public:
void RemoveConnections(CONNECTION_TYPE* pConnections);
void CompareBoundingBox(float box[6]);
void SetPieceInfo(PieceInfo* pPieceInfo);
- void FileLoad(File* file, char* name);
- void FileSave(File* file, Group* pGroups);
+ bool FileLoad(File& file, char* name);
+ void FileSave(File& file, Group* pGroups);
void CalculateConnections(CONNECTION_TYPE* pConnections, unsigned short nTime, bool bAnimation, bool bForceRebuild, bool bFixOthers);
void UpdatePosition(unsigned short nTime, bool bAnimation);
- bool CalculatePositionRotation(unsigned short nTime, bool bAnimation, float pos[3], float rot[4]);
- void Move(unsigned short nTime, bool bAnimation, bool bAddKey, float x, float y, float z);
- void ChangeKey(unsigned short nTime, bool bAnimation, bool bAddKey, float* param, unsigned char nKeyType);
+ void Move(unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz);
+
void DoGroup(Group* pGroup);
void UnGroup(Group* pGroup);
Group* GetTopGroup();
@@ -155,13 +149,8 @@ public:
*/
protected:
void LineFacet(float* p1, float* p2, float* p3, float* p4, LC_CLICKLINE* pLine);
- void RemoveKeys();
void BuildDrawInfo();
- // Position
- LC_PIECE_KEY* m_pAnimationKeys;
- LC_PIECE_KEY* m_pInstructionKeys;
-
// Atributes
PieceInfo* m_pPieceInfo;
Group* m_pGroup;