/*---------------------------------------------------------------------------* Project: NintendoWare File: demo_Utility.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: 25056 $ *---------------------------------------------------------------------------*/ #include #include #include #include #include #include namespace nw { namespace demo { const nw::math::VEC3 Utility::CAMERA_POSITION = nw::math::VEC3(7.0f, 3.5f, -5.0f); const nw::math::VEC3 Utility::TARGET_POSITION = nw::math::VEC3(0.0f, 0.0f, 0.0f); const f32 Utility::NEAR_CLIP = 0.1f; const f32 Utility::FAR_CLIP = 1000.0f; const f32 Utility::FOVY_RADIAN = NW_MATH_DEG_TO_RAD(37.8f); const nw::math::VEC2 Utility::PROJECTION_CENTER = nw::math::VEC2(0.0f, 0.0f); const f32 Utility::PROJECTION_HEIGHT = 1.0f; //---------------------------------------- ResourceSet* Utility::LoadResources(ResourceArray& resourceArray, const wchar_t* resourcePath, os::IAllocator* allocator) { ResourceSet resourceSet; // 現在、デバイスメモリ上に読み込む方式にのみ対応しています。 // テクスチャをロードするには128byteアライメントを行う必要があります。 const int resourceAlignment = 128; resourceSet.buffer = nw::demo::Utility::LoadFile(allocator, resourcePath, resourceAlignment); if (!resourceSet.buffer) { return NULL; } resourceSet.resource = nw::gfx::ResGraphicsFile(&(resourceSet.buffer.front())); bool isPushed = resourceArray.push_back(resourceSet); NW_ASSERT(isPushed); return &(resourceArray.back()); } //---------------------------------------- nw::gfx::Camera* Utility::CreateCamera( os::IAllocator* allocator, const nw::math::VEC3& cameraPosition, const nw::math::VEC3& targetPosition, f32 nearClip, f32 farClip, f32 fovyRadian, nw::math::PivotDirection pivotDirection, f32 wScale ) { NW_POINTER_ASSERT(allocator); nw::gfx::LookAtTargetViewUpdater* viewUpdater = nw::gfx::LookAtTargetViewUpdater::Create(allocator); NW_POINTER_ASSERT(viewUpdater); nw::gfx::ResLookAtTargetViewUpdater resViewUpdater = nw::gfx::ResStaticCast(viewUpdater->GetResource()); resViewUpdater.SetTargetPosition(targetPosition); resViewUpdater.SetUpwardVector(0.0f,1.0f,0.0f); nw::gfx::PerspectiveProjectionUpdater* projectionUpdater = nw::gfx::PerspectiveProjectionUpdater::Create(allocator); NW_POINTER_ASSERT(projectionUpdater); projectionUpdater->SetPivotDirection(pivotDirection); nw::gfx::ResPerspectiveProjectionUpdater resProjectionUpdater = nw::gfx::ResStaticCast( projectionUpdater->GetResource()); resProjectionUpdater.SetNear(nearClip); resProjectionUpdater.SetFar(farClip); resProjectionUpdater.SetFovy(fovyRadian); nw::gfx::Camera* camera = nw::gfx::Camera::DynamicBuilder() .MaxChildren(0) .MaxCallbacks(0) .ViewUpdater(viewUpdater) .ProjectionUpdater(projectionUpdater) .Create(allocator); NW_POINTER_ASSERT(camera); camera->Transform().SetTranslate(cameraPosition); camera->SetWScale(wScale); return camera; } //---------------------------------------- nw::gfx::Camera* Utility::CreateAimCamera( os::IAllocator* allocator, const nw::math::VEC3& cameraPosition, const nw::math::VEC3& targetPosition, f32 nearClip, f32 farClip, f32 fovyRadian, nw::math::PivotDirection pivotDirection, f32 wScale ) { NW_POINTER_ASSERT(allocator); nw::gfx::AimTargetViewUpdater* viewUpdater = nw::gfx::AimTargetViewUpdater::Create(allocator); NW_POINTER_ASSERT(viewUpdater); nw::gfx::ResAimTargetViewUpdater resViewUpdater = nw::gfx::ResStaticCast(viewUpdater->GetResource()); resViewUpdater.SetTargetPosition(targetPosition); resViewUpdater.SetTwist(0.0f); nw::gfx::PerspectiveProjectionUpdater* projectionUpdater = nw::gfx::PerspectiveProjectionUpdater::Create(allocator); NW_POINTER_ASSERT(projectionUpdater); projectionUpdater->SetPivotDirection(pivotDirection); nw::gfx::ResPerspectiveProjectionUpdater resProjectionUpdater = nw::gfx::ResStaticCast( projectionUpdater->GetResource()); resProjectionUpdater.SetNear(nearClip); resProjectionUpdater.SetFar(farClip); resProjectionUpdater.SetFovy(fovyRadian); nw::gfx::Camera* camera = nw::gfx::Camera::DynamicBuilder() .MaxChildren(0) .MaxCallbacks(0) .ViewUpdater(viewUpdater) .ProjectionUpdater(projectionUpdater) .Create(allocator); NW_POINTER_ASSERT(camera); camera->Transform().SetTranslate(cameraPosition); camera->SetWScale(wScale); return camera; } //---------------------------------------- nw::gfx::Camera* Utility::CreateFrustumCamera( os::IAllocator* allocator, const nw::math::VEC3& cameraPosition, const nw::math::VEC3& targetPosition, f32 nearClip, f32 farClip, const nw::math::VEC2& projectionCenter, f32 projectionHeight, nw::math::PivotDirection pivotDirection, f32 wScale ) { NW_POINTER_ASSERT(allocator); nw::gfx::LookAtTargetViewUpdater* viewUpdater = nw::gfx::LookAtTargetViewUpdater::Create(allocator); NW_POINTER_ASSERT(viewUpdater); nw::gfx::ResLookAtTargetViewUpdater resViewUpdater = nw::gfx::ResStaticCast(viewUpdater->GetResource()); resViewUpdater.SetTargetPosition(targetPosition); resViewUpdater.SetUpwardVector(0.0f,1.0f,0.0f); nw::gfx::FrustumProjectionUpdater* projectionUpdater = nw::gfx::FrustumProjectionUpdater::Create(allocator); NW_POINTER_ASSERT(projectionUpdater); projectionUpdater->SetPivotDirection(pivotDirection); nw::gfx::ResFrustumProjectionUpdater resProjectionUpdater = nw::gfx::ResStaticCast( projectionUpdater->GetResource()); resProjectionUpdater.SetNear(nearClip); resProjectionUpdater.SetFar(farClip); nw::gfx::ResProjectionRect rect = resProjectionUpdater.GetRect(); rect.m_Center = projectionCenter; rect.m_Height = projectionHeight; resProjectionUpdater.SetRect(rect); nw::gfx::Camera* camera = nw::gfx::Camera::DynamicBuilder() .MaxChildren(0) .MaxCallbacks(0) .ViewUpdater(viewUpdater) .ProjectionUpdater(projectionUpdater) .Create(allocator); NW_POINTER_ASSERT(camera); camera->Transform().SetTranslate(cameraPosition); camera->SetWScale(wScale); return camera; } //---------------------------------------- nw::gfx::Camera* Utility::CreateOrthoCamera( os::IAllocator* allocator, const nw::math::VEC3& cameraPosition, const nw::math::VEC3& targetPosition, f32 nearClip, f32 farClip, const nw::math::VEC2& projectionCenter, f32 projectionHeight, nw::math::PivotDirection pivotDirection, f32 wScale ) { NW_POINTER_ASSERT(allocator); nw::gfx::LookAtTargetViewUpdater* viewUpdater = nw::gfx::LookAtTargetViewUpdater::Create(allocator); NW_POINTER_ASSERT(viewUpdater); nw::gfx::ResLookAtTargetViewUpdater resViewUpdater = nw::gfx::ResStaticCast(viewUpdater->GetResource()); resViewUpdater.SetTargetPosition(targetPosition); resViewUpdater.SetUpwardVector(0.0f,1.0f,0.0f); nw::gfx::OrthoProjectionUpdater* projectionUpdater = nw::gfx::OrthoProjectionUpdater::Create(allocator); NW_POINTER_ASSERT(projectionUpdater); projectionUpdater->SetPivotDirection(pivotDirection); nw::gfx::ResOrthoProjectionUpdater resProjectionUpdater = nw::gfx::ResStaticCast( projectionUpdater->GetResource()); resProjectionUpdater.SetNear(nearClip); resProjectionUpdater.SetFar(farClip); nw::gfx::ResProjectionRect rect = resProjectionUpdater.GetRect(); rect.m_Center = projectionCenter; rect.m_Height = projectionHeight; resProjectionUpdater.SetRect(rect); nw::gfx::Camera* camera = nw::gfx::Camera::DynamicBuilder() .MaxChildren(0) .MaxCallbacks(0) .ViewUpdater(viewUpdater) .ProjectionUpdater(projectionUpdater) .Create(allocator); NW_POINTER_ASSERT(camera); camera->Transform().SetTranslate(cameraPosition); camera->SetWScale(wScale); return camera; } //---------------------------------------- void Utility::CreateStereoCameras( nw::gfx::Camera** ppBaseCamera, nw::gfx::Camera** ppLeftCamera, nw::gfx::Camera** ppRightCamera, os::IAllocator* allocator, const nw::math::VEC3& cameraPosition, const nw::math::VEC3& targetPosition, f32 nearClip, f32 farClip, f32 fovyRadian, f32 wScale ) { NW_POINTER_ASSERT(ppBaseCamera); NW_POINTER_ASSERT(ppLeftCamera); NW_POINTER_ASSERT(ppRightCamera); NW_POINTER_ASSERT(allocator); *ppBaseCamera = nw::demo::Utility::CreateCamera( allocator, cameraPosition, targetPosition, nearClip, farClip, fovyRadian, nw::math::PIVOT_NONE ); (*ppBaseCamera)->SetWScale(wScale); *ppLeftCamera = nw::gfx::Camera::DynamicBuilder() .MaxChildren(0) .MaxCallbacks(0) .Create(allocator); NW_POINTER_ASSERT(*ppLeftCamera); (*ppLeftCamera)->SetWScale(wScale); *ppRightCamera = nw::gfx::Camera::DynamicBuilder() .MaxChildren(0) .MaxCallbacks(0) .Create(allocator); NW_POINTER_ASSERT(*ppRightCamera); (*ppRightCamera)->SetWScale(wScale); } //---------------------------------------- void Utility::SetCameraAspectRatio( nw::gfx::Camera* camera, f32 aspectRatio ) { NW_POINTER_ASSERT(camera); f32 fovy; f32 near; f32 far; camera->GetPerspective(&fovy, NULL, &near, &far); camera->SetPerspective(fovy, aspectRatio, near, far); camera->UpdateCameraMatrix(); } //---------------------------------------- nw::gfx::IRenderTarget* Utility::CreateUpperScreenBuffer( os::IAllocator* allocator, nw::demo::RenderSystem::Description& renderDescription ) { // オンスクリーンバッファは縦と横が逆になっているため、 // 幅と高さを逆に設定しています。 return nw::gfx::IRenderTarget::Builder() .BufferSize( renderDescription.upperScreenDescription.height, renderDescription.upperScreenDescription.width ) .ColorFormat(renderDescription.renderColorFormat) .Create(allocator); } //---------------------------------------- nw::gfx::IRenderTarget* Utility::CreateLowerScreenBuffer( os::IAllocator* allocator, nw::demo::RenderSystem::Description& renderDescription ) { // オンスクリーンバッファは縦と横が逆になっているため、 // 幅と高さを逆に設定しています。 return nw::gfx::IRenderTarget::Builder() .BufferSize( renderDescription.lowerScreenDescription.height, renderDescription.lowerScreenDescription.width ) .ColorFormat(renderDescription.renderColorFormat) .Create(allocator); } //---------------------------------------- nw::gfx::SceneNode* Utility::CreateSceneNode( os::IAllocator* deviceAllocator, nw::gfx::ResSceneObject resource, bool isAnimationEnabled, nw::gfx::Model::BufferOption bufferOption, s32 maxAnimObjects ) { nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder() .Resource(resource) .BufferOption(bufferOption) .MaxAnimObjectsPerGroup(maxAnimObjects) .IsAnimationEnabled(isAnimationEnabled) .CreateObject(deviceAllocator, deviceAllocator); nw::gfx::SceneNode* node = nw::ut::DynamicCast(sceneObject); return node; } //---------------------------------------- ut::MoveArray Utility::LoadFile( os::IAllocator* allocator, const wchar_t* filePath, u32 align /* = 32 */ ) { nn::fs::FileReader fileReader; nn::Result result = fileReader.TryInitialize(filePath); if (result.IsFailure()) { return nw::ut::MoveArray(); } s32 fileSize = static_cast(fileReader.GetSize()); void* memory = allocator->Alloc(fileSize, static_cast(align)); nw::ut::MoveArray buffer(memory, fileSize, allocator); buffer.resize(fileSize); fileReader.Read(&buffer.front(), fileSize); fileReader.Finalize(); // コンテナを返してますが、バッファはコピーされません。 // 所有権が移動します。 return buffer; } //---------------------------------------- nw::gfx::AnimGroup* Utility::GetAnimGroup( nw::gfx::SceneObject* object, AnimationType animationType ) { // アニメーショングループを取得します。 nw::gfx::AnimGroup* animGroup = NULL; switch (animationType) { case SKELETAL_ANIMATION: { nw::gfx::SkeletalModel* skeletalModel = nw::ut::DynamicCast(object); NW_ASSERT(skeletalModel); animGroup = skeletalModel->GetSkeletalAnimGroup(); } break; case MATERIAL_ANIMATION: { nw::gfx::Model* model = nw::ut::DynamicCast(object); NW_ASSERT(model); animGroup = model->GetMaterialAnimGroup(); } break; case VISIBILITY_ANIMATION: { nw::gfx::Model* model = nw::ut::DynamicCast(object); NW_ASSERT(model); animGroup = model->GetVisibilityAnimGroup(); } break; case CAMERA_ANIMATION: { nw::gfx::Camera* camera = nw::ut::DynamicCast(object); NW_ASSERT(camera); animGroup = camera->GetAnimGroup(); } break; case LIGHT_ANIMATION: { nw::gfx::Light* light = nw::ut::DynamicCast(object); NW_ASSERT(light); animGroup = light->GetAnimGroup(); } break; default: NW_FATAL_ERROR("Invalid animation type"); } return animGroup; } //---------------------------------------- bool Utility::BindAnimationObject( nw::gfx::SceneObject* object, nw::gfx::AnimObject* animObject, AnimationType animationType ) { nw::gfx::AnimGroup* animGroup = GetAnimGroup(object, animationType); if (!animGroup) { return false; } if (animObject->TryBind( animGroup ).IsFailure()) { return false; } switch (animationType) { case SKELETAL_ANIMATION: { nw::gfx::SkeletalModel* skeletalModel = nw::ut::DynamicCast(object); NW_ASSERT(skeletalModel); skeletalModel->SetSkeletalAnimObject(animObject); } break; case MATERIAL_ANIMATION: { nw::gfx::Model* model = nw::ut::DynamicCast(object); NW_ASSERT(model); model->SetMaterialAnimObject(animObject); } break; case VISIBILITY_ANIMATION: { nw::gfx::Model* model = nw::ut::DynamicCast(object); NW_ASSERT(model); model->SetVisibilityAnimObject(animObject); } break; case CAMERA_ANIMATION: { nw::gfx::Camera* camera = nw::ut::DynamicCast(object); NW_ASSERT(camera); camera->SetAnimObject(animObject); } break; case LIGHT_ANIMATION: { nw::gfx::Light* light = nw::ut::DynamicCast(object); NW_ASSERT(light); light->SetAnimObject(animObject); } break; default: NW_FATAL_ERROR("Invalid animation type"); } return true; } namespace internal { //---------------------------------------- bool IsTerminatingImpl() { return false; } } // namespace internal } /* namespace demo */ } /* namespace nw */