⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keyframer.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}
		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 + -