LinkFactory.cpp

#include "StdAfx.h"
#include "LinkFactory.h"


#include "Link.h"
#include "JointFactory.h"

#include "Shape.h"
#include "ConnectionRelationSetting.h"


using namespace Core;
using namespace Robotics;

using namespace System;
using namespace System::Diagnostics;


/// XMLから生成する [ Constructor ]
LinkFactory::LinkFactory( System::Xml::XmlElement^ root ) :
    m_element( root )
{
}


/// 生成する
Link^ LinkFactory::Create()
{
    // 関節の生成を行うメソッドを生成する
    JointFactory^ factory = gcnew JointFactory( m_element );

    // ... 関節を生成する
    Joint^ joint = factory->Create();


    // インスタンスを生成する
    return FactoryMethod( joint );
}

/// インスタンスを生成して返す
Link^ LinkFactory::FactoryMethod( Joint^ joint )
{
    // リンクを生成する
    Link^ result = gcnew Link( joint, m_element );

    result->Mass = GetMass();                       // 質量
    result->CenterOfGravity = GetCenterOfGravity(); // 重心

    return result;
}


/// 重心を取得する
Robotics::PositionVector^ LinkFactory::GetCenterOfGravity()
{
    PositionVector^ result = gcnew PositionVector();

    // 定義されている質量の数だけ繰り返す
    for each( Xml::XmlElement^ node in m_element[ "centerOfGravity" ]->ChildNodes )
    {
        double mass = Double::Parse( node->GetAttribute( "mass" ) );    // 質量
        PositionVector^ centerOfGravity = gcnew PositionVector( node ); // 重心

        // 質量とベクトルの積の和を求める
        result += ( mass * centerOfGravity );
    }

    double totalMass = GetMass();   // 全体の質量

    // 全体の重心を求めて返す
    return( result / totalMass );
}

/// 質量を取得する
double LinkFactory::GetMass()
{
    double result = 0.0;

    // 定義されている質量の数だけ繰り返す
    for each( Xml::XmlElement^ node in m_element[ "centerOfGravity" ]->ChildNodes )
    {
        // 質量を取得して加算する
        result += Double::Parse( node->GetAttribute( "mass" ) );
    }
    Debug::Assert( 0.0 <= result, "質量は正数である" );

    return result;
}


/// リンクの配列を生成する
Links^ LinkFactory::CreateLinks( System::Xml::XmlElement^ root )
{
    Debug::WriteLine( "リンクの配列を生成する" );


    // リンク要素のノードリストを取得する
    Xml::XmlNodeList^ nodeList = root->GetElementsByTagName( "link" );

    // ... リンクの配列を生成する
    Links^ result = gcnew Links( nodeList->Count );


    // 全てのリンクを生成する
    int index = 0;
    for each( Xml::XmlElement^ node in nodeList )
    {
        // リンクの生成を行うメソッドを生成する
        LinkFactory^ factory = gcnew LinkFactory( node );

        // ... リンクを生成する
        result[ index++ ] = factory->Create();


        /// @todo インデックスの指定の方法を見直す。
    }

    // リンクの接続関係を設定する
    ConnectionRelationSetting::Create( result, root );

    return result;
}