/** * @file * @brief Utility無しの物理世界の構築 * @date 2009-09-16 Selene ver 1.11にて適当なサンプルソース(Sample.cpp)にコピペ動作確認 */ /*--------------------------------------------------------------------------*/ /* Include */ /*--------------------------------------------------------------------------*/ #include using namespace Selene; // 重力係数 static const Kernel::Math::VectorS GRAVITY = Kernel::Math::VectorS( 0.0f, -9.80619920f, 0.0f ); // BOX生成時のデータ static Kernel::Math::Vector3 BOX_COUNT = Kernel::Math::Vector3( 2, 5, 2 ); static Kernel::Math::Vector3 BOX_CENTER_POS = Kernel::Math::Vector3( 0.0f, 0.5f, 20.0f ); static Kernel::Math::Vector3 BOX_SIZE = Kernel::Math::Vector3( 1.0f, 1.0f, 1.0f ); // 球生成時のデータ static float SPHERE_RADIUS = 1.5f; static Kernel::Math::Vector3 SPHERE_VEROCITY = Kernel::Math::Vector3( 0.0f, 0.0f, 50.0f ); // BOX生成関数 static void CreateDynamicsBox( Kernel::Math::Vector3 &BoxCount, Kernel::Math::Vector3 &vCenterPos, Kernel::Math::Vector3 &vSize ); // Seleneコア Engine::ICore* g_pCore = NULL; /*--------------------------------------------------------------------------*/ /* WinMain */ /*--------------------------------------------------------------------------*/ int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) { // ----------------------------------------------------------- // // はじめのお約束作業 // めんどうなのでコメント削除 // // ----------------------------------------------------------- const Point2DI SCREEN_SIZE( 512, 512 ); Engine::Renderer::Standard::IRenderer* pRenderer = NULL; Engine::Renderer::Standard::SParameter RendererParameter; Kernel::Math::Camera CameraTable[Engine::Renderer::Standard::VIEW_TYPE_MAX]; Engine::Graphics::Simple::ITriangleRenderer* pTriangleRenderer; Engine::Graphics::Simple::ILineRenderer* pLineRenderer; #if defined(SLN_DEVELOP) if ( !Selene::InitializeEngine( L"Selene.Develop.dll" ) ) #elif defined(SLN_DEBUG) if ( !Selene::InitializeEngine( L"Selene.Debug.dll" ) ) #else // SLN_DEBUG if ( !Selene::InitializeEngine( L"Selene.dll" ) ) #endif { return 1; } g_pCore = Selene::CreateCore(); if ( !g_pCore->Initialize( L"Selene Sample Program", SCREEN_SIZE, true, true ) ) { return 1; } if ( !g_pCore->CreateGraphicsManager() ) { return 1; } if ( !g_pCore->CreateRendererManager() ) { return 1; } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-= // ファイルマネージャーの生成 // ファイル読み込みを行うためのエンジンを初期化 g_pCore->CreateFileManager(); // 暗号解除用プラグイン // ファイルを暗号化してパックしてある場合に // 暗号解除に利用するプラグインと解除用のパスワードを指定 // 暗号化はデータの中身を隠す目的としては有用だが // 当然読み込み速度を犠牲にするので使いどころに注意。 // g_pCore->GetFileManager()->SetCryptPlugin( L"Plugin/File/Crypt.dll", "Sample-Password" ); // ファイル読み込み対象のパスのリスト // 指定ディレクトリ以下を順に検索していく // // Sample/ の Data/test.dat と SampleNew/ の /Data/test.dat があった場合は // 後に指定した方が検索対象として登録される。 // リリース後にパッチ等でデータの差し替え尾を行う場合に // 古い方のデータを変更せずソースの変更もなしで差し替える事が可能 // const wchar_t* pFilePathList[] = { L"../../Media", // 最初に検索するディレクトリ NULL, // NULLで検索終了 }; g_pCore->GetFileManager()->UpdateRootPath( pFilePathList ); pRenderer = g_pCore->GetRendererManager()->CreateStandardRenderer(); RendererParameter.UseProgrammableShader = true; // 利用可能ならシェーダーを使って描画 RendererParameter.Effect.IsFog = false; // フォグの有無 RendererParameter.Effect.IsScattering = false; // スキャッタリングの有無 RendererParameter.Effect.IsDepthOfField = false; // 被写界深度処理の有無 RendererParameter.Effect.IsHighDynamicRange = false; // HDRレンダリングの有無 RendererParameter.Effect.IsSoftParticle = false; // ソフトパーティクルの有無 RendererParameter.Effect.IsMotionBlur = false; // モーションブラーの有無 RendererParameter.Effect.IsAmbientOcclusion = false; // アンビエント隠蔽 RendererParameter.Effect.ShadowType = Engine::Renderer::Standard::SHADOW_MAP_DISABLE; // 影マップの種類 pRenderer->Initialize( RendererParameter ); pRenderer->CreateView( Engine::Renderer::Standard::VIEW_TYPE_01, RectI(0,0,SCREEN_SIZE.x,SCREEN_SIZE.y), true, ColorF(0.5f,0.8f,0.5f,1.0f), true ); pRenderer->SetParameter_MainLight( sVectorS( 0.5f, 2.0f,-2.0f ), // 平行光源の位置 sVectorS( 0.0f, 0.0f, 0.0f ), // 平行光源のターゲット位置 sVectorS( 0.8f, 0.8f, 0.8f ), // 平行光源の色 sVectorS( 0.4f, 0.4f, 0.4f ), // 半球ライトの地面からの照り返し sVectorS( 0.2f, 0.2f, 0.2f ) ); // 半球ライトの空からの色 // ----------------------------------------------------------- // // // ここからが本番 // // // ----------------------------------------------------------- // 物理世界構築 { g_pCore->CreateDynamicsManager(); g_pCore->GetDynamicsManager()->SetGravity( GRAVITY ); // 重力セット } { // デバッグポリゴン描画用簡易インターフェイス pLineRenderer = g_pCore->GetGraphicsManager()->CreateLineRenderer(); pTriangleRenderer = g_pCore->GetGraphicsManager()->CreateTriangleRenderer(); Kernel::Math::VectorS LightDirection = Kernel::Math::VecS::Normal3( Kernel::Math::VectorS( -1.5f, -1.0f, 0.8f ) ); Kernel::Math::VectorS LightColor(0.5f,0.5f,0.5f); Kernel::Math::VectorS LightAmbient(0.5f,0.5f,0.5f); pTriangleRenderer->SetSimpleLight( LightDirection, // ディレクション LightColor, // 色 LightAmbient ); // アンビエント // 床 { // 無限平面 Engine::Dynamics::Body::IPlane* pPlane; pPlane = g_pCore->GetDynamicsManager()->CreateFloor(); // 摩擦 pPlane->SetFriction( 1.00f ); // 反射 pPlane->SetRestitution( 0.3f ); // デバッグ描画 pPlane->CreateDebugShape( ColorF( 0.9f, 0.9f, 0.9f ) ); } // ダイナミクスボックス生成 { CreateDynamicsBox( BOX_COUNT, BOX_CENTER_POS, BOX_SIZE ); } // 球 { // 球 Engine::Dynamics::Body::ISphere* pSphere; pSphere = g_pCore->GetDynamicsManager()->CreateSphere( SPHERE_RADIUS, 8.0f, Kernel::Math::VectorS( 0.0f, SPHERE_RADIUS / 2, 0.0f ) ); // 初速 pSphere->SetLinearVelocity( SPHERE_VEROCITY ); // デバッグ描画 pSphere->CreateDebugShape( ColorF( 0.6f, 1.0f, 0.6f ) ); } } // ----------------------------------------------------------- // 生成したプリミティブをレンダラーに登録する // これ重要! // ----------------------------------------------------------- // pRenderer->AddDrawObject(pMapModel, true); //------------------------------------------------------------ // メインループ // Seleneを利用する上でのメインループの書き方です // ICore::DoEvent()でOSのイベント処理を行います。 //------------------------------------------------------------ static float fCameraAngleY = 0.0f; while(g_pCore->DoEvent(60)) { // 物理世界の時間を経過させる g_pCore->GetDynamicsManager()->StepSimulation(); //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // 画面のクリア //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- g_pCore->GetGraphicsManager()->Clear(true, false, ColorF(0.7f,0.7f,0.7f)); //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // フレームの開始 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- g_pCore->FrameBegin(); //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // カメラの設定 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // パースペクティブ行列 Kernel::Math::Camera *pCamera = &CameraTable[Engine::Renderer::Standard::VIEW_TYPE_01]; pCamera->PerspectiveFovLH( Kernel::Math::DegToPi( 45 ), toF(SCREEN_SIZE.x)/toF(SCREEN_SIZE.y), 0.1f, 2000.0f ); pCamera->LookAt( sVectorS( 0.0f, 10.0f, -25.0f ), // 位置 sVectorS( 0.0f, 0.0f, 0.0f ), // 注視位置 sVectorS( 0.0f, 0.0f, 1.0f ) ); // 上向き角度 // 回転 pCamera->SetWorldMatrix( pCamera->GetViewMatrixInverse() * Kernel::Math::MatX::RotationY( fCameraAngleY ) ); fCameraAngleY += 0.001f; // フラスタム更新 pCamera->UpdateFrustum(); // ----------------------------------------------------------- // カメラを利用して描画 // pRenderer->AddDrawObjectしたやつを描画するっぽい // ----------------------------------------------------------- pRenderer->SimpleRendering(CameraTable); // ----------------------------------------------------------- // 物理世界のデバッグ描画 // SimpleRenderingの後にやること // ----------------------------------------------------------- ColorF ModulateColor( 1.0f, 1.0f, 1.0f, 1.0f ); ModulateColor = pRenderer->ConvertSceneColor( ModulateColor ); // ワールド⇒プロジェクション sMatrix mCamera = pCamera->GetViewMatrix() * pCamera->GetProjectionMatrix(); // 描画開始 pLineRenderer->CacheReset( Engine::Graphics::Simple::LINE_MODE_3D ); pLineRenderer->SetCameraMatrix( mCamera ); pLineRenderer->SetModulateColor( ModulateColor ); pTriangleRenderer->CacheReset( Engine::Graphics::Simple::TRIANGLE_MODE_3D ); pTriangleRenderer->SetCameraMatrix( mCamera ); pTriangleRenderer->SetModulateColor( ModulateColor ); // 物理の独自3D描画 g_pCore->GetDynamicsManager()->DrawDebugShape( pLineRenderer, pTriangleRenderer, NULL ); // 描画完了 pLineRenderer->CacheDraw(); pTriangleRenderer->CacheDraw(); //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // フレームの終了 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- g_pCore->FrameEnd(); //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // 画面の更新 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- g_pCore->GetGraphicsManager()->Present(); } //------------------------------------------------------------ // 終了処理 // 終了時には生成したインターフェイスを解放し、 // 最後にICoreを解放してください。 //------------------------------------------------------------ /* if ( pRenderer != NULL ) { pRenderer->RemoveDrawObject( pMapModel ); } */ SAFE_RELEASE(pRenderer); SAFE_RELEASE(g_pCore); Selene::FinalizeEngine(); return 0; } //-------------------------------------------------------------------------------- /** * @brief 物理世界用ボックス作成 * * @param[in] BoxCount 箱生成数 XYZそれぞれが数として対応 * @param[in] vCenterPos 箱の集合の中心位置 * @param[in] vSize 箱一つ分のサイズ **/ //-------------------------------------------------------------------------------- void CreateDynamicsBox( Kernel::Math::Vector3 &BoxCount, Kernel::Math::Vector3 &vCenterPos, Kernel::Math::Vector3 &vSize ) { // 箱 for ( Sint32 z = 0; z < BoxCount.x; z++ ) { for ( Sint32 y = 0; y < BoxCount.y; y++ ) { for ( Sint32 x = 0; x < BoxCount.z; x++ ) { Kernel::Math::Vector3 vPosition( toF(x) * (vSize.x * 1.01f) - ((BoxCount.x * 0.5f) - 0.5f), toF(y) * (vSize.y * 1.01f), toF(z) * (vSize.z * 1.01f) - ((BoxCount.z * 0.5f) - 0.5f) ); vPosition = Kernel::Math::Vec3::Add( vPosition, vCenterPos ); // 箱 Engine::Dynamics::Body::IBox* pBox; pBox = g_pCore->GetDynamicsManager()->CreateBox( vSize, 1.0f, vPosition ); // 摩擦 pBox->SetFriction( 0.2f ); // 反射 pBox->SetRestitution( 0.1f ); // デバッグ描画 pBox->CreateDebugShape( ColorF( 1.0f, 0.6f, 0.6f ) ); } } } }