Model.h

#pragma once


namespace Core
{
    ref class Pose;

    ref class Link;
    ref class SupportPolygon;

    ref class Distinction;
    ref class PositionAndPostureChangeEventArgs;

    typedef array< Link^ > Links;
    typedef System::Collections::Generic::List< Link^ > LinkList;


    /// モデル
    [ System::ComponentModel::TypeConverter( CustomProperty::DisplayNameTypeConverter::typeid ) ]   // プロパティ表示の変換
    public ref class Model
    {
    // Construction --------------------------------------------------------
    public:
        Model( Core::Links^ links );

        ~Model() { Model::!Model(); }
        !Model();


    // Operation -----------------------------------------------------------
    public:
        void InitializeState();
        void DoPose( Pose^ pose );

        int GetLinkIndex( Core::Link^ link );
        void LinkGrounded( Distinction^ link );

        Robotics::PositionVector^ CalculateCenterOfGravity( LinkList^ links );
        double CalculateMass( LinkList^ links );

        void CreateFigure( Microsoft::DirectX::Direct3D::Device^ device );
        void Render( Microsoft::DirectX::Direct3D::Device^ device );

    private:
        Core::Link^ GetLinkInLowestPosition();
        bool EvadeCollisionWithGround();


    // Event Handler -------------------------------------------------------
    public:
        void Recompute( System::Object^ sender, System::EventArgs^ e );

    private:
        void LinkPositionAndPostureChanged( System::Object^ sender, PositionAndPostureChangeEventArgs^ e );


    // Event ---------------------------------------------------------------
    public:
        event System::EventHandler^ StateChanged;   ///< 状態変化イベント


    // Attribute ===========================================================
    private:
        Links^ m_links;            ///< リンク

        System::String^ m_name;    ///< 名称
        double m_voltage;          ///< 電圧[ V ]

        Microsoft::DirectX::Direct3D::Mesh^ m_centerOfGravityFigure;   ///< 重心の図形


    // Property ------------------------------------------------------------
    public:
        /// リンク
        [ System::ComponentModel::Browsable( false ) ]  // 参照不可
        property Link^ Link[ System::String^ ]
        {
            Core::Link^ get( System::String^ name );
        }

        /// リンク
        [ System::ComponentModel::Browsable( false ) ]  // 参照不可
        property Links^ Links
        {
            Core::Links^ get()
            {
                return m_links;
            }
        }

        /// リンクのリスト
        [ System::ComponentModel::Browsable( false ) ]  // 参照不可
        property LinkList^ LinkLists
        {
            LinkList^ get()
            {
                // Arrayを Listにして返す
                return gcnew LinkList(
                    ( System::Collections::Generic::IEnumerable< Core::Link^ >^ )m_links
                );
            }
        }


        /// 名称
        [ System::ComponentModel::CategoryAttribute( "全般" ) ]
        [ CustomProperty::DisplayName( "名称" ) ]
        property System::String^ Name
        {
            System::String^ get()
            {
                return m_name;
            }
            void set( System::String^ value )
            {
                m_name = value;
            }
        }

        /// 電圧[ V ]
        [ System::ComponentModel::CategoryAttribute( "全般" ) ]
        [ CustomProperty::DisplayName( "電圧" ) ]
        property double Voltage
        {
            double get()
            {
                return m_voltage;
            }
            void set( double value )
            {
                m_voltage = value;
            }
        }


        /// 支持多角形[ m ] (ワールド座標系)
        [ System::ComponentModel::Browsable( false ) ]  // 参照不可
        property SupportPolygon^ SupportPolygon
        {
            Core::SupportPolygon^ get();
        }


        /// 重心[ m ] (ワールド座標系)
        [ System::ComponentModel::Browsable( false ) ]  // 参照不可
        property Robotics::PositionVector^ CenterOfGravity
        {
            Robotics::PositionVector^ get();
        }

        /// 質量[ kg ]
        [ System::ComponentModel::CategoryAttribute( "全般" ) ]
        [ CustomProperty::DisplayName( "質量") ]
        [ System::ComponentModel::Description( "モデル全体の質量を表します。" ) ]
        property double Mass
        {
            double get();
        }
    };
}