#include "ordeviceskeleton_device.h"
#define ORDEVICESKELETON_CLASS ORDEVICESKELETON_CLASSNAME
#define ORDEVICESKELETON_NAME ORDEVICESKELETON_CLASSSTR
#define ORDEVICESKELETON_LABEL "OR - Skeleton Device"
#define ORDEVICESKELETON_DESC "OR - Skeleton Device"
#define ORDEVICESKELETON_PREFIX "SkeletonDevice"
#define ORDEVICESKELETON_ICON "devices_body.png"
ORDEVICESKELETON_CLASS,
ORDEVICESKELETON_LABEL,
ORDEVICESKELETON_DESC,
ORDEVICESKELETON_ICON );
bool ORDeviceSkeleton::FBCreate()
{
ModelTemplate.Children.Add(mRootTemplate);
mHierarchyIsDefined = false;
mHasAnimationToTranspose = false;
mPlotting = false;
SamplingPeriod = FBTime(0,0,1)/sSKDataBuffer::SIM_FPS;
UseReferenceTransformation = true;
FBSystem().TheOne().OnUIIdle.Add(
this,(
FBCallback) &ORDeviceSkeleton::EventUIIdle );
return true;
}
void ORDeviceSkeleton::FBDestroy()
{
ParentClass::FBDestroy();
FBSystem().TheOne().OnUIIdle.Remove(
this,(
FBCallback) &ORDeviceSkeleton::EventUIIdle );
}
bool ORDeviceSkeleton::DeviceOperation( kDeviceOperations pOperation )
{
switch (pOperation)
{
case kOpInit: return Init();
case kOpStart: return Start();
case kOpAutoDetect: break;
case kOpStop: return Stop();
case kOpReset: return Reset();
case kOpDone: return Done();
}
return ParentClass::DeviceOperation(pOperation);
}
bool ORDeviceSkeleton::Init()
{
FBProgress lProgress;
lProgress.Caption = "Device";
lProgress.Text = "Initializing device...";
if(!mHardware.GetSetupInfo())
{
Information = "Could not get channel information from device.";
return false;
}
mHierarchyIsDefined = false;
Bind();
return true;
}
bool ORDeviceSkeleton::Done()
{
FBProgress lProgress;
lProgress.Caption = "Device";
lProgress.Text = "Shutting down device...";
UnBind();
return true;
}
bool ORDeviceSkeleton::Reset()
{
Stop();
return Start();
}
bool ORDeviceSkeleton::Start()
{
FBProgress Progress;
Progress.Caption = "Setting up device";
if(! mHardware.Open() )
{
Information = "Could not open device";
return false;
}
Progress.Text = "Device found, scanning for channel information...";
Information = "Retrieving channel information";
if(! mHardware.StartDataStream() )
{
Information = "Could not start data stream.";
return false;
}
return true;
}
bool ORDeviceSkeleton::Stop()
{
FBProgress lProgress;
lProgress.Caption = "Shutting down device";
if(! mHardware.StopDataStream() )
{
Information = "Could not stop data stream.";
return false;
}
lProgress.Text = "Closing device communication";
Information = "Closing device communication";
if(! mHardware.Close() )
{
Information = "Could not close device";
return false;
}
return false;
}
void ORDeviceSkeleton::DefineHierarchy()
{
if( !mHierarchyIsDefined && GetChannelCount() > 0 )
{
int lParent;
for(
int i=0;
i< GetChannelCount();
i++)
{
lParent = GetChannelParent(
i);
if(lParent == -1)
{
mRootTemplate->Children.Add(mChannels[
i].mModelTemplate);
}
else
{
mChannels[lParent].mModelTemplate->Children.Add(mChannels[
i].mModelTemplate);
}
}
mHierarchyIsDefined = true;
}
}
bool ORDeviceSkeleton::ReadyForCharacterize()
{
return mHierarchyIsDefined && GetChannelCount() > 0;
}
void ORDeviceSkeleton::ProcessGlobalToLocal()
{
SetupLocalGlobal(true);
FBModel* lModel;
for(i = 0; i < lModels.GetCount(); i++)
lModels[i]->Selected = false;
lModels.Clear();
for(i = 0; i < GetChannelCount(); i++)
{
if(mChannels[i].mModelTemplate && (lModel = mChannels[i].mModelTemplate->Model) !=
NULL)
{
lModel->Selected = true;
lModels.Add(lModel);
}
}
mPlotting = true;
mSystem.CurrentTake->PlotTakeOnSelected(SamplingPeriod);
mPlotting = false;
for(i = 0; i < lModels.GetCount(); i++)
lModels[i]->Selected = false;
SetupLocalGlobal(false);
bool ApplyReferenceTransformation = UseReferenceTransformation && mRootTemplate->Model;
if(ApplyReferenceTransformation)
{
mRootTemplate->Model->Translation.SetData(&x);
mRootTemplate->Model->Rotation.SetData(&x);
}
}
void ORDeviceSkeleton::SetupLocalGlobal(bool pGlobal)
{
for( int i = 0; i < GetChannelCount(); i++ )
{
if( mChannels[i].mTAnimNode )
{
mChannels[
i].mTAnimNode->SetBufferType(pGlobal);
}
if( mChannels[i].mRAnimNode )
{
mChannels[
i].mRAnimNode->SetBufferType(pGlobal);
}
}
}
bool ORDeviceSkeleton::ModelTemplateUnBindNotify( int pIndex, FBModelTemplate* pModelTemplate)
{
if(pModelTemplate->Model && pModelTemplate->Model == mRootTemplate->Model && !ObjectInProcess)
{
FBPlayerControl().TheOne().EvaluationPause();
for( int i = 0; i < GetChannelCount(); i++ )
{
if(mChannels[i].mTAnimNode)
{
mChannels[
i].mModelTemplate->Model->Translation.SetAnimated(
true);
FBAnimationNode* lNode = mChannels[
i].mModelTemplate->Model->Translation.GetAnimationNode();
FBVector3d lVector(mChannels[i].mModelTemplate->Model->Translation);
lNode->SetCandidate(lVector.mValue);
}
if(mChannels[i].mRAnimNode)
{
mChannels[
i].mModelTemplate->Model->Rotation.SetAnimated(
true);
FBAnimationNode* lNode = mChannels[
i].mModelTemplate->Model->Rotation.GetAnimationNode();
FBVector3d lVector(mChannels[i].mModelTemplate->Model->Rotation);
lNode->SetCandidate(lVector.mValue);
}
}
FBPlayerControl().TheOne().EvaluationResume();
}
return true;
}
void ORDeviceSkeleton::Bind()
{
for( i = 0; i < GetChannelCount(); i++ )
{
if( !mChannels[i].mTAnimNode )
{
FBString lName( GetChannelName(i), " T" );
}
if( !mChannels[i].mRAnimNode )
{
FBString lName( GetChannelName(i), " R" );
}
if(!mChannels[i].mModelTemplate)
{
mChannels[
i].mModelTemplate->Bindings.Add(mChannels[i].mTAnimNode);
mChannels[
i].mModelTemplate->Bindings.Add(mChannels[i].mRAnimNode);
}
}
DefineHierarchy();
}
void ORDeviceSkeleton::UnBind()
{
for( i = 0; i < GetChannelCount(); i++ )
{
if( mChannels[i].mTAnimNode )
{
if( mChannels[i].mModelTemplate )
{
mChannels[
i].mModelTemplate->Bindings.Remove(mChannels[i].mTAnimNode);
}
}
if( mChannels[i].mRAnimNode )
{
if( mChannels[i].mModelTemplate )
{
mChannels[
i].mModelTemplate->Bindings.Remove(mChannels[i].mRAnimNode);
}
}
if( mRootTemplate->Children.Find(mChannels[i].mModelTemplate) >= 0 )
{
mRootTemplate->Children.Remove(mChannels[i].mModelTemplate);
}
if( mChannels[i].mTAnimNode )
{
AnimationNodeDestroy(mChannels[i].mTAnimNode);
}
if( mChannels[i].mRAnimNode )
{
AnimationNodeDestroy(mChannels[i].mRAnimNode);
}
mChannels[
i].mTAnimNode =
NULL;
mChannels[
i].mRAnimNode =
NULL;
if( mChannels[i].mModelTemplate )
{
mChannels[
i].mModelTemplate->Children.RemoveAll();
}
}
for( i = 0; i < GetChannelCount(); i++ )
{
delete mChannels[
i].mModelTemplate;
mChannels[
i].mModelTemplate =
NULL;
}
}
bool ORDeviceSkeleton::AnimationNodeNotify(FBAnimationNode* pAnimationNode ,FBEvaluateInfo* pEvaluateInfo)
{
kReference lReference = pAnimationNode->Reference;
if (lReference>=10000)
{
FBSVector Scal;
FBMatrix GlobalNodeTransformation, GlobalReferenceTransformation;
bool ApplyReferenceTransformation = UseReferenceTransformation && mRootTemplate->Model;
if(ApplyReferenceTransformation)
{
mRootTemplate->Model->GetMatrix(GlobalReferenceTransformation,
kModelTransformation,
true,pEvaluateInfo);
}
for(int i=0;i<GetChannelCount();i++)
{
if(mChannels[i].mTAnimNode && mChannels[i].mRAnimNode)
{
bool lDontWrite = false;
if ((!pAnimationNode->Live || mPlotting) && mChannels[
i].mModelTemplate->Model)
{
mChannels[
i].mModelTemplate->Model->Translation.GetAnimationNode()->Evaluate(Pos.mValue,pEvaluateInfo->GetLocalTime(),
false);
mChannels[
i].mModelTemplate->Model->Rotation.GetAnimationNode()->Evaluate(Rot.mValue,pEvaluateInfo->GetLocalTime(),
false);
} else if (pAnimationNode->Live)
{
Pos[0] = mHardware.GetDataTX(i);
Pos[1] = mHardware.GetDataTY(i);
Pos[2] = mHardware.GetDataTZ(i);
Rot[0] = mHardware.GetDataRX(i);
Rot[1] = mHardware.GetDataRY(i);
Rot[2] = mHardware.GetDataRZ(i);
} else
{
lDontWrite = true;
}
if(ApplyReferenceTransformation)
{
FBGetGlobalMatrix(GlobalNodeTransformation,GlobalReferenceTransformation,GlobalNodeTransformation);
}
if(!lDontWrite)
{
if (!pAnimationNode->Live || mPlotting)
{
mChannels[
i].mRAnimNode->WriteData( Rot.mValue, pEvaluateInfo);
mChannels[
i].mTAnimNode->WriteData( Pos.mValue, pEvaluateInfo);
} else
{
mChannels[
i].mRAnimNode->WriteGlobalData( Rot.mValue, pEvaluateInfo );
mChannels[
i].mTAnimNode->WriteGlobalData( Pos.mValue, pEvaluateInfo );
}
}
}
}
}
return ParentClass::AnimationNodeNotify( pAnimationNode , pEvaluateInfo);
}
void ORDeviceSkeleton::DeviceTransportNotify( kTransportMode pMode, FBTime pTime, FBTime pSystem )
{
if(pMode==kPreparePlay)
{
mHardware.ResetPacketTimeOffset(pTime);
}
}
void ORDeviceSkeleton::DeviceIONotify( kDeviceIOs pAction,FBDeviceNotifyInfo &pDeviceNotifyInfo)
{
switch (pAction)
{
case kIOPlayModeWrite:
case kIOStopModeWrite:
{
}
break;
case kIOStopModeRead:
case kIOPlayModeRead:
{
FBTime lEvalTime;
lEvalTime = pDeviceNotifyInfo.GetLocalTime();
while(mHardware.FetchDataPacket(lEvalTime))
{
DeviceRecordFrame(lEvalTime,pDeviceNotifyInfo);
AckOneSampleReceived();
}
}
break;
}
}
void ORDeviceSkeleton::RecordingDoneAnimation( FBAnimationNode* pAnimationNode )
{
FBDevice::RecordingDoneAnimation( pAnimationNode );
mHasAnimationToTranspose = true;
}
void ORDeviceSkeleton::DeviceRecordFrame(FBTime &pTime,FBDeviceNotifyInfo &pDeviceNotifyInfo)
{
{
FBAnimationNode* Data;
bool ApplyReferenceTransformation = UseReferenceTransformation && mRootTemplate->Model;
FBMatrix GlobalReferenceTransformation;
if(ApplyReferenceTransformation)
for (i=0; i<GetChannelCount(); i++)
{
if (mChannels[i].mTAnimNode)
{
Data = mChannels[
i].mTAnimNode->GetAnimationToRecord();
if (Data)
{
Pos[0] = mHardware.GetDataTX(i);
Pos[1] = mHardware.GetDataTY(i);
Pos[2] = mHardware.GetDataTZ(i);
if(ApplyReferenceTransformation)
Data->KeyAdd(pTime, Pos);
}
}
if (mChannels[i].mRAnimNode)
{
Data = mChannels[
i].mRAnimNode->GetAnimationToRecord();
if (Data)
{
Rot[0] = mHardware.GetDataRX(i);
Rot[1] = mHardware.GetDataRY(i);
Rot[2] = mHardware.GetDataRZ(i);
if(ApplyReferenceTransformation)
{
FBMatrix GRM;
}
Data->KeyAdd(pTime, Rot);
}
}
}
}
}
bool ORDeviceSkeleton::FbxStore(FBFbxObject* pFbxObject,
kFbxObjectStore pStoreWhat)
{
{
}
return true;
}
bool ORDeviceSkeleton::FbxRetrieve(FBFbxObject* pFbxObject,
kFbxObjectStore pStoreWhat)
{
{
}
return true;
}
{
if(mHasAnimationToTranspose)
{
mHasAnimationToTranspose = false;
ProcessGlobalToLocal();
}
}