/*---------------------------------------------------------------------------* Project: NintendoWare File: SmTouchPanelCamera.cpp Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 1 $ *---------------------------------------------------------------------------*/ #include #include #include #include "../include/SmTouchPanelCamera.h" #include "../include/SmTouchPanelStatus.h" namespace { //---------------------------------------- // コンストラクタ SmTouchPanelCamera::SmTouchPanelCamera( SmCamera* smcamera ) : SmMessage( NULL ), m_SmCamera( smcamera ), m_IsGrab( false ), m_TouchPanelPosLastX( 0 ), m_TouchPanelPosLastY( 0 ), m_TouchPanelPosX( 0 ), m_TouchPanelPosY( 0 ), m_DegX( 0.f ), m_DegY( 0.f ) { // カメラ視点 m_SmCamera->GetPosition( &m_CameraPos ); // カメラ注視点 m_SmCamera->GetTarget( &m_CameraTarget ); // カメラ向き基準 m_CameraToward.x = m_CameraTarget.x - m_CameraPos.x; m_CameraToward.y = m_CameraTarget.y - m_CameraPos.y; m_CameraToward.z = m_CameraTarget.z - m_CameraPos.z; m_CameraToward.Normalize(); // タッチパネルのコリジョンを設定します。 m_Collision.SetRect( 40, 70, 160, 160 ); } //---------------------------------------- // メッセージ受信 bool SmTouchPanelCamera::ReceveMessage( SmMessageType type, void* object, uint targetId ) { NW_UNUSED_VARIABLE(targetId); SmTouchPanelStatus* touchPanelStaus = NULL; bool ret = false; switch( type ) { case SM_MESSAGE_TUCHPANEL_PRESS: { touchPanelStaus = static_cast(object); NW_NULL_ASSERT( touchPanelStaus ); if ( m_Collision.CheckInner( touchPanelStaus->GetX(), touchPanelStaus->GetY() ) ) { // 他処理で使用中でなければ if ( !touchPanelStaus->IsGrab() ) { // 掴む touchPanelStaus->Grab(); m_IsGrab = true; } } } break; case SM_MESSAGE_TUCHPANEL_MOTION: { touchPanelStaus = static_cast(object); NW_NULL_ASSERT( touchPanelStaus ); // カメラを更新 if ( m_IsGrab ) { // 座標を更新 m_TouchPanelPosLastX = static_cast( m_TouchPanelPosX ); m_TouchPanelPosLastY = static_cast( m_TouchPanelPosY ); m_TouchPanelPosX = static_cast( touchPanelStaus->GetX() ); m_TouchPanelPosY = static_cast( touchPanelStaus->GetY() ); // カメラを計算 calcCamera(); } } break; case SM_MESSAGE_TUCHPANEL_RELEASE: { touchPanelStaus = static_cast(object); NW_NULL_ASSERT( touchPanelStaus ); // 放す if ( m_IsGrab ) { touchPanelStaus->UnGrab(); m_IsGrab = false; } } break; default: break; } return ret; } //---------------------------------------- // 描画 void SmTouchPanelCamera::Render() { Sm2DDynamicPrimPC prim; if ( prim.Begin( 4, GL_TRIANGLE_STRIP, 0.f, 0.f ) ) { prim.SetVertex( m_Collision.GetX(), m_Collision.GetY(), nw::ut::Color8::YELLOW ); prim.SetVertex( m_Collision.GetX(), m_Collision.GetY() + m_Collision.GetHeight(), nw::ut::Color8::YELLOW ); prim.SetVertex( m_Collision.GetX() + m_Collision.GetWidth(), m_Collision.GetY(), nw::ut::Color8::YELLOW ); prim.SetVertex( m_Collision.GetX() + m_Collision.GetWidth(), m_Collision.GetY() + m_Collision.GetHeight(), nw::ut::Color8::YELLOW ); prim.End(); } if ( m_IsGrab ) { if ( prim.Begin( 4, GL_TRIANGLE_STRIP, 0.f, 0.f ) ) { prim.SetVertex( m_TouchPanelPosX, m_TouchPanelPosY, nw::ut::Color8::RED ); prim.SetVertex( m_TouchPanelPosX, m_TouchPanelPosY + 4.f, nw::ut::Color8::RED ); prim.SetVertex( m_TouchPanelPosX + 4.f, m_TouchPanelPosY, nw::ut::Color8::RED ); prim.SetVertex( m_TouchPanelPosX + 4.f, m_TouchPanelPosY + 4.f, nw::ut::Color8::RED ); prim.End(); } } } //---------------------------------------- // ウォークスルーカメラ計算 void SmTouchPanelCamera::calcCamera() { nw::math::MTX34 matrixRaotY; matrixRaotY.SetupIdentity(); nw::math::VEC3 toward; f32 degX = 0.f; // 画面中央左右で首振り { #define _DEGREE_SPEED (0.3f) #define _DEGREE_MAX (15.f) s32 centerX = m_Collision.GetX() + m_Collision.GetWidth()/2.f; s32 centerY = m_Collision.GetY() + m_Collision.GetHeight()/2.f; if ( m_TouchPanelPosX < centerX ) { if ( m_DegY < _DEGREE_MAX ) { m_DegY += _DEGREE_SPEED; } } else { if ( m_DegY > -_DEGREE_MAX ) { m_DegY -= _DEGREE_SPEED; } } if ( m_TouchPanelPosY < centerY ) { if ( m_DegX < _DEGREE_MAX ) { m_DegX += _DEGREE_SPEED; } } else { if ( m_DegX > -_DEGREE_MAX ) { m_DegX -= _DEGREE_SPEED; } } } // 向きを更新 MTX34RotXYZDeg( &matrixRaotY, m_DegX, m_DegY, 0.f ); VEC3TransformNormal( &toward, &matrixRaotY, &m_CameraToward ); // 位置と向きから注視点 m_CameraTarget.x = m_CameraPos.x + toward.x * 10.f; m_CameraTarget.y = m_CameraPos.y + toward.y * 10.f; m_CameraTarget.z = m_CameraPos.z + toward.z * 10.f; // カメラ更新 updateCamera(); } //---------------------------------------- // カメラ更新 void SmTouchPanelCamera::updateCamera() { // todo: // 無効 if ( !GetEnable() ) return; m_SmCamera->SetPosition( &m_CameraPos ); m_SmCamera->SetTarget( &m_CameraTarget ); } } // namespace