This file contains the actual GameObject, which is derived from the RakNet::Replica3 class. This handles the creation and deletion of other players objects, serializing changes for my game object to other players and also getting the new position from other player objects and updating them in my scene.
You will also notice a class called CompC4dObjectImpl. This is created internally instead of the header file so that we don't have to include the cinema4d "c4d.h" file in the main header file. This makes the code cleaner and also avoids conflicting head definitions.
The main parts in this file to look at are UpdatePosition and DeserializeConstruction.
The UpdatePosition method will update the location of the object in Cinema4D. The position value is set when Deserialize is called. This gets called when another player moves one of their objects and the information is serialized and sent through to all other clients.
The DeserializeConstruction gets called when a new player joins the "game". This gets called only once and is where the player object is created. You will also notice that I am actually using the Object Type to determine what gets created. This allows us to change the Ocube in RakNetStuff.cpp to any kind of object we want.
#include "GameObject.h"
#include "RakNetworkFactory.h"
#include "NetworkIDManager.h"
#include "RakNetTime.h"
#include "GetTime.h"
#include "c4d.h"
class CompC4DObjectImpl
{
public:
CompC4DObjectImpl()
{
}
void UpdatePosition(bool localObject)
{
BaseObject *obj = static_cast(m_object->ForceGetLink());
if(obj->IsDirty(DIRTY_MATRIX) || !localObject)
{
Vector newPos = obj->GetPos();
if(newPos != m_position)
{
if(localObject)
{
m_position = newPos;
}
else
{
obj->SetPos(m_position);
obj->Message(MSG_UPDATE);
}
}
}
}
void Init(BaseDocument *pDoc, BaseObject *pObject)
{
m_doc->SetLink(pDoc);
m_object->SetLink(pObject);
}
public:
AutoAlloc m_object;
AutoAlloc m_doc;
Vector m_position;
};
DataStructures::Multilist GameObject::m_gameObjectList;
GameObject::GameObject()
: m_Impl(NULL)
{
lastUpdate=RakNet::GetTime();
m_gameObjectList.Push(this,__FILE__,__LINE__);
}
GameObject::~GameObject()
{
m_gameObjectList.RemoveAtKey(this,true,__FILE__,__LINE__);
gDelete(m_Impl);
}
bool GameObject::Init(BaseDocument *pDoc, BaseObject *pObject)
{
if(m_Impl)
gDelete(m_Impl);
m_Impl = gNew CompC4DObjectImpl();
if(m_Impl)
{
m_Impl->Init(pDoc, pObject);
return TRUE;
}
return FALSE;
}
RakNet::RM3QuerySerializationResult GameObject::QuerySerialization(RakNet::Connection_RM3 *destinationConnection)
{
return QuerySerialization_PeerToPeer(destinationConnection);
}
void GameObject::WriteAllocationID(RakNet::BitStream *allocationIdBitstream) const
{
allocationIdBitstream->Write(RakNet::RakString("GameObject"));
}
void GameObject::UpdatePosition(bool localObject)
{
m_Impl->UpdatePosition(localObject);
}
void GameObject::SerializeConstruction(RakNet::BitStream *constructionBitstream, RakNet::Connection_RM3 *destinationConnection)
{
constructionBitstream->Write(m_Impl->m_object->ForceGetLink()->GetType());
constructionBitstream->Write(m_Impl->m_position);
}
bool GameObject::DeserializeConstruction(RakNet::BitStream *constructionBitstream, RakNet::Connection_RM3 *sourceConnection)
{
LONG objectType = Ocube;
Vector position;
constructionBitstream->Read(objectType);
constructionBitstream->Read(position);
BaseObject *pTemp = BaseObject::Alloc(objectType);
if(pTemp)
{
BaseDocument *doc = GetActiveDocument();
doc->InsertObject(pTemp,NULL,NULL);
m_Impl = gNew CompC4DObjectImpl();
m_Impl->Init(doc,pTemp);
m_Impl->m_position = position;
EventAdd(EVENT_FORCEREDRAW);
}
return true;
}
RakNet::RM3SerializationResult GameObject::Serialize(RakNet::SerializeParameters *serializeParameters)
{
serializeParameters->outputBitstream[0].Write(m_Impl->m_position);
return RakNet::RM3SR_BROADCAST_IDENTICALLY;
}
void GameObject::Deserialize(RakNet::DeserializeParameters *deserializeParameters)
{
deserializeParameters->serializationBitstream[0].Read(m_Impl->m_position);
}
void GameObject::PostDeserializeConstruction(RakNet::Connection_RM3 *sourceConnection)
{
}
void GameObject::PreDestruction(RakNet::Connection_RM3 *sourceConnection)
{
}
Comments
Post a Comment