📄 keyframer.cpp
字号:
}
break;
case MID_SAVEOBJECT:
{
Save((HMESSAGEWRITE)pData, (DDWORD)fData);
}
break;
case MID_LOADOBJECT:
{
Load((HMESSAGEREAD)pData, (DDWORD)fData);
}
break;
default : break;
}
return B2BaseClass::EngineMessageFn(messageID, pData, fData);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::ObjectMessageFn
//
// PURPOSE: Handle object messages
//
// ----------------------------------------------------------------------- //
DDWORD KeyFramer::ObjectMessageFn(HOBJECT hSender, DDWORD messageID, HMESSAGEREAD hRead)
{
if (!g_pServerDE) return 0;
switch (messageID)
{
case MID_TRIGGER:
{
HSTRING hMsg = g_pServerDE->ReadFromMessageHString(hRead);
char* pMsg = g_pServerDE->GetStringData(hMsg);
if (!pMsg) return 0;
if (_mbsicmp((const unsigned char*)pMsg, (const unsigned char*)"ON") == 0 || _mbsicmp((const unsigned char*)pMsg, (const unsigned char*)"TRIGGER") == 0)
{
GoActive();
}
else if (_mbsicmp((const unsigned char*)pMsg, (const unsigned char*)"OFF") == 0)
{
m_bActive = DFALSE;
g_pServerDE->SetNextUpdate(m_hObject, 0.0f);
}
g_pServerDE->FreeString(hMsg);
}
break;
default : break;
}
return B2BaseClass::ObjectMessageFn(hSender, messageID, hRead);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::ReadProp
//
// PURPOSE: Set property value
//
// ----------------------------------------------------------------------- //
DBOOL KeyFramer::ReadProp(ObjectCreateStruct *pStruct)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !pStruct) return DFALSE;
char buf[MAX_CS_FILENAME_LEN];
buf[0] = '\0';
pServerDE->GetPropString("ObjectName", buf, MAX_CS_FILENAME_LEN);
if (buf[0]) m_hstrObjectName = pServerDE->CreateString(buf);
buf[0] = '\0';
pServerDE->GetPropString("BaseKeyName", buf, MAX_CS_FILENAME_LEN);
if (buf[0]) m_hstrBaseKeyName = pServerDE->CreateString(buf);
pServerDE->GetPropBool("StartActive", &m_bStartActive);
pServerDE->GetPropBool("Looping", &m_bLooping);
pStruct->m_NextUpdate = 0.001f;
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::InitialUpdate()
//
// PURPOSE: First update
//
// ----------------------------------------------------------------------- //
DBOOL KeyFramer::InitialUpdate(DVector* pMovement)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE) return DFALSE;
// Mark this object as savable
DDWORD dwFlags = g_pServerDE->GetObjectUserFlags(m_hObject);
dwFlags |= USRFLG_SAVEABLE;
g_pServerDE->SetObjectUserFlags(m_hObject, dwFlags);
// Build key list during the first update so that we can
// ensure that the keys have all been loaded.
pServerDE->SetNextUpdate(m_hObject, 0.001f);
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::Update()
//
// PURPOSE: Update
//
// ----------------------------------------------------------------------- //
DBOOL KeyFramer::Update(DVector* pMovement)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE) return DFALSE;
if (!m_pObjectList)
{
if (!BuildObjectList())
return DFALSE;
}
// Need to check this here (instead of InitialUpdate)...This insures
// that all the Keys have been added to the world...
if (m_bFirstUpdate)
{
m_bFirstUpdate = DFALSE;
CreateKeyList();
if (m_bStartActive)
{
GoActive();
}
// Don't start processing keys until the next update
return DTRUE;
}
// See if we are even supposed to be here (today)...
if (!m_bActive)
{
pServerDE->SetNextUpdate(m_hObject, 0.0f);
return DTRUE;
}
else
{
pServerDE->SetNextUpdate(m_hObject, 0.001f);
}
// increment timer
m_fCurTime += pServerDE->GetFrameTime();
// process all keys that we might have passed by
while (m_pCurKey)
{
if (m_pCurKey->keyData.m_fRealTime > m_fCurTime) break;
ProcessKey (m_pCurKey);
m_pCurKey = m_pCurKey->pNext;
}
// are we at the end of the key list?
if (!m_pCurKey)
{
m_pCurKey = m_pKeys;
m_fCurTime = 0.0f;
if (!m_bLooping)
{
m_bActive = DFALSE;
return DTRUE;
}
}
// interpolate position
if (m_pPosition1 && m_pPosition2)
{
if (m_fCurTime >= m_pPosition1->keyData.m_fRealTime)
{
const float c_fMinTimeDelta = 0.001f;
float fTimeDelta = (m_pPosition2->keyData.m_fRealTime - m_pPosition1->keyData.m_fRealTime);
DVector posNew, pos1, pos2;
VEC_INIT(posNew);
DRotation rotNew, rot1, rot2;
ROT_INIT(rotNew);
if (fTimeDelta <= c_fMinTimeDelta)
{
VEC_COPY(posNew, m_pPosition2->keyData.m_vPos);
ROT_COPY(rotNew, m_pPosition2->keyData.m_rRot);
}
else if (m_fCurTime <= m_pPosition2->keyData.m_fRealTime)
{
float t = (m_fCurTime - m_pPosition1->keyData.m_fRealTime) / fTimeDelta;
// get the new position from position 1's position
VEC_COPY(pos1, m_pPosition1->keyData.m_vPos);
VEC_COPY(pos2, m_pPosition2->keyData.m_vPos);
VEC_LERP(posNew, pos1, pos2, t);
// get the new angle from position 1's angle
ROT_COPY(rot1, m_pPosition1->keyData.m_rRot);
ROT_COPY(rot2, m_pPosition2->keyData.m_rRot);
pServerDE->InterpolateRotation(&rotNew, &rot1, &rot2, t);
}
else
{
return DTRUE;
}
// Now add the relative position and rotation to every object in the list
long i = 0;
ObjectLink* pLink = m_pObjectList->m_pFirstLink;
while (pLink)
{
pServerDE->GetObjectPos(pLink->m_hObject, &pos1);
VEC_ADD (pos1, posNew, m_pOffsets[i]);
/*
char msg[80];
sprintf (msg, "moving to: %.2f, %.2f, %.2f", pos1.x, pos1.y, pos1.z);
pServerDE->BPrint (msg);
*/
pServerDE->GetObjectRotation(pLink->m_hObject, &rot1);
VEC_ADD(rot1.m_Vec, rotNew.m_Vec, m_pRotations[i].m_Vec);
rot1.m_Spin = rotNew.m_Spin + m_pRotations[i].m_Spin;
// If object is a camera, and it has a link, don't rotate it.
DBOOL bRotate = DTRUE;
if(pServerDE->IsKindOf(pServerDE->GetObjectClass(pLink->m_hObject), pServerDE->GetClass("CameraObj")))
{
CameraObj *pCamera = (CameraObj*)pServerDE->HandleToObject(pLink->m_hObject);
if (pCamera->GetLinkObject())
{
bRotate = DFALSE;
}
}
pServerDE->MoveObject(pLink->m_hObject, &pos1);
if (bRotate)
pServerDE->RotateObject(pLink->m_hObject, &rot1);
i++;
pLink = pLink->m_pNext;
}
}
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::Save
//
// PURPOSE: Save the object
//
// ----------------------------------------------------------------------- //
void KeyFramer::Save(HMESSAGEWRITE hWrite, DDWORD dwSaveFlags)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !hWrite) return;
pServerDE->WriteToMessageFloat(hWrite, m_fCurTime);
pServerDE->WriteToMessageHString(hWrite, m_hstrObjectName);
pServerDE->WriteToMessageHString(hWrite, m_hstrBaseKeyName);
pServerDE->WriteToMessageByte(hWrite, m_bStartActive);
pServerDE->WriteToMessageByte(hWrite, m_bLooping);
pServerDE->WriteToMessageByte(hWrite, m_bActive);
pServerDE->WriteToMessageByte(hWrite, m_bFirstUpdate);
pServerDE->WriteToMessageByte(hWrite, m_nNumKeys);
// Determine the position in the list of m_pCurKey, m_pPosition1, and
// m_pPosition2. Also, save out m_pKeys...
int nCurKeyIndex = -1;
int nPosition1Index = -1;
int nPosition2Index = -1;
KEYNODE* pCurKey = m_pKeys;
for (int i=0; i < m_nNumKeys && pCurKey; i++)
{
if (m_pCurKey == pCurKey)
{
nCurKeyIndex = i;
}
if (m_pPosition1 == pCurKey)
{
nPosition1Index = i;
}
if (m_pPosition2 == pCurKey)
{
nPosition2Index = i;
}
pCurKey->keyData.Save(hWrite, dwSaveFlags);
pCurKey = pCurKey->pNext;
}
// Save out the positions of our pointer data members...
pServerDE->WriteToMessageFloat(hWrite, (DFLOAT) nCurKeyIndex);
pServerDE->WriteToMessageFloat(hWrite, (DFLOAT) nPosition1Index);
pServerDE->WriteToMessageFloat(hWrite, (DFLOAT) nPosition2Index);
for (i=0; i < m_nNumKeys; i++)
{
pServerDE->WriteToMessageVector(hWrite, &(m_pOffsets[i]));
pServerDE->WriteToMessageRotation(hWrite, &(m_pRotations[i]));
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: KeyFramer::Load
//
// PURPOSE: Load the object
//
// ----------------------------------------------------------------------- //
void KeyFramer::Load(HMESSAGEREAD hRead, DDWORD dwLoadFlags)
{
CServerDE* pServerDE = GetServerDE();
if (!pServerDE || !hRead) return;
m_fCurTime = pServerDE->ReadFromMessageFloat(hRead);
m_hstrObjectName = pServerDE->ReadFromMessageHString(hRead);
m_hstrBaseKeyName = pServerDE->ReadFromMessageHString(hRead);
m_bStartActive = (DBOOL) pServerDE->ReadFromMessageByte(hRead);
m_bLooping = (DBOOL) pServerDE->ReadFromMessageByte(hRead);
m_bActive = (DBOOL) pServerDE->ReadFromMessageByte(hRead);
m_bFirstUpdate = (DBOOL) pServerDE->ReadFromMessageByte(hRead);
m_nNumKeys = pServerDE->ReadFromMessageByte(hRead);
// Build the m_pKeys data member...
KEYNODE* pNode = DNULL;
for (int i=0; i < m_nNumKeys; i++)
{
if (!m_pKeys)
{
m_pKeys = new KEYNODE;
pNode = m_pKeys;
}
else if (pNode)
{
pNode->pNext = new KEYNODE;
pNode->pNext->pPrev = pNode;
pNode = pNode->pNext;
}
if (pNode)
{
pNode->keyData.Load(hRead, dwLoadFlags);
}
}
// Determine the positions of our pointer data members...
int nCurKeyIndex = (int) pServerDE->ReadFromMessageFloat(hRead);
int nPosition1Index = (int) pServerDE->ReadFromMessageFloat(hRead);
int nPosition2Index = (int) pServerDE->ReadFromMessageFloat(hRead);
KEYNODE* pCurKey = m_pKeys;
for (i=0; i < m_nNumKeys && pCurKey; i++)
{
if (nCurKeyIndex == i)
{
m_pCurKey = pCurKey;
}
if (nPosition1Index == i)
{
m_pPosition1 = pCurKey;
}
if (nPosition2Index == i)
{
m_pPosition2 = pCurKey;
}
pCurKey = pCurKey->pNext;
}
for (i=0; i < m_nNumKeys; i++)
{
pServerDE->ReadFromMessageVector(hRead, &(m_pOffsets[i]));
pServerDE->ReadFromMessageRotation(hRead, &(m_pRotations[i]));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -