1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: demo_Utility.cpp
4
5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Revision: 25056 $
14 *---------------------------------------------------------------------------*/
15
16 #include <nw/types.h>
17 #include <nw/os.h>
18 #include <nw/ut/ut_Inlines.h>
19 #include <nw/demo/demo_Utility.h>
20 #include <nw/gfx.h>
21
22 #include <nn/fs.h>
23
24 namespace nw {
25 namespace demo {
26
27 const nw::math::VEC3 Utility::CAMERA_POSITION = nw::math::VEC3(7.0f, 3.5f, -5.0f);
28 const nw::math::VEC3 Utility::TARGET_POSITION = nw::math::VEC3(0.0f, 0.0f, 0.0f);
29 const f32 Utility::NEAR_CLIP = 0.1f;
30 const f32 Utility::FAR_CLIP = 1000.0f;
31 const f32 Utility::FOVY_RADIAN = NW_MATH_DEG_TO_RAD(37.8f);
32 const nw::math::VEC2 Utility::PROJECTION_CENTER = nw::math::VEC2(0.0f, 0.0f);
33 const f32 Utility::PROJECTION_HEIGHT = 1.0f;
34
35
36 //----------------------------------------
37 ResourceSet*
LoadResources(ResourceArray & resourceArray,const wchar_t * resourcePath,os::IAllocator * allocator)38 Utility::LoadResources(ResourceArray& resourceArray, const wchar_t* resourcePath, os::IAllocator* allocator)
39 {
40 ResourceSet resourceSet;
41 // 現在、デバイスメモリ上に読み込む方式にのみ対応しています。
42 // テクスチャをロードするには128byteアライメントを行う必要があります。
43 const int resourceAlignment = 128;
44 resourceSet.buffer = nw::demo::Utility::LoadFile(allocator, resourcePath, resourceAlignment);
45
46 if (!resourceSet.buffer)
47 {
48 return NULL;
49 }
50
51 resourceSet.resource = nw::gfx::ResGraphicsFile(&(resourceSet.buffer.front()));
52
53 bool isPushed = resourceArray.push_back(resourceSet);
54
55 NW_ASSERT(isPushed);
56
57 return &(resourceArray.back());
58 }
59
60 //----------------------------------------
61 nw::gfx::Camera*
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)62 Utility::CreateCamera(
63 os::IAllocator* allocator,
64 const nw::math::VEC3& cameraPosition,
65 const nw::math::VEC3& targetPosition,
66 f32 nearClip,
67 f32 farClip,
68 f32 fovyRadian,
69 nw::math::PivotDirection pivotDirection,
70 f32 wScale
71 )
72 {
73 NW_POINTER_ASSERT(allocator);
74
75 nw::gfx::LookAtTargetViewUpdater* viewUpdater =
76 nw::gfx::LookAtTargetViewUpdater::Create(allocator);
77 NW_POINTER_ASSERT(viewUpdater);
78
79 nw::gfx::ResLookAtTargetViewUpdater resViewUpdater =
80 nw::gfx::ResStaticCast<nw::gfx::ResLookAtTargetViewUpdater>(viewUpdater->GetResource());
81
82 resViewUpdater.SetTargetPosition(targetPosition);
83 resViewUpdater.SetUpwardVector(0.0f,1.0f,0.0f);
84
85 nw::gfx::PerspectiveProjectionUpdater* projectionUpdater =
86 nw::gfx::PerspectiveProjectionUpdater::Create(allocator);
87 NW_POINTER_ASSERT(projectionUpdater);
88
89 projectionUpdater->SetPivotDirection(pivotDirection);
90
91 nw::gfx::ResPerspectiveProjectionUpdater resProjectionUpdater =
92 nw::gfx::ResStaticCast<nw::gfx::ResPerspectiveProjectionUpdater>(
93 projectionUpdater->GetResource());
94 resProjectionUpdater.SetNear(nearClip);
95 resProjectionUpdater.SetFar(farClip);
96 resProjectionUpdater.SetFovy(fovyRadian);
97
98 nw::gfx::Camera* camera =
99 nw::gfx::Camera::DynamicBuilder()
100 .MaxChildren(0)
101 .MaxCallbacks(0)
102 .ViewUpdater(viewUpdater)
103 .ProjectionUpdater(projectionUpdater)
104 .Create(allocator);
105
106 NW_POINTER_ASSERT(camera);
107
108 camera->Transform().SetTranslate(cameraPosition);
109 camera->SetWScale(wScale);
110
111 return camera;
112 }
113
114 //----------------------------------------
115 nw::gfx::Camera*
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)116 Utility::CreateAimCamera(
117 os::IAllocator* allocator,
118 const nw::math::VEC3& cameraPosition,
119 const nw::math::VEC3& targetPosition,
120 f32 nearClip,
121 f32 farClip,
122 f32 fovyRadian,
123 nw::math::PivotDirection pivotDirection,
124 f32 wScale
125 )
126 {
127 NW_POINTER_ASSERT(allocator);
128
129 nw::gfx::AimTargetViewUpdater* viewUpdater =
130 nw::gfx::AimTargetViewUpdater::Create(allocator);
131 NW_POINTER_ASSERT(viewUpdater);
132
133 nw::gfx::ResAimTargetViewUpdater resViewUpdater =
134 nw::gfx::ResStaticCast<nw::gfx::ResAimTargetViewUpdater>(viewUpdater->GetResource());
135
136 resViewUpdater.SetTargetPosition(targetPosition);
137 resViewUpdater.SetTwist(0.0f);
138
139 nw::gfx::PerspectiveProjectionUpdater* projectionUpdater =
140 nw::gfx::PerspectiveProjectionUpdater::Create(allocator);
141 NW_POINTER_ASSERT(projectionUpdater);
142
143 projectionUpdater->SetPivotDirection(pivotDirection);
144
145 nw::gfx::ResPerspectiveProjectionUpdater resProjectionUpdater =
146 nw::gfx::ResStaticCast<nw::gfx::ResPerspectiveProjectionUpdater>(
147 projectionUpdater->GetResource());
148 resProjectionUpdater.SetNear(nearClip);
149 resProjectionUpdater.SetFar(farClip);
150 resProjectionUpdater.SetFovy(fovyRadian);
151
152 nw::gfx::Camera* camera =
153 nw::gfx::Camera::DynamicBuilder()
154 .MaxChildren(0)
155 .MaxCallbacks(0)
156 .ViewUpdater(viewUpdater)
157 .ProjectionUpdater(projectionUpdater)
158 .Create(allocator);
159
160 NW_POINTER_ASSERT(camera);
161
162 camera->Transform().SetTranslate(cameraPosition);
163 camera->SetWScale(wScale);
164
165 return camera;
166 }
167
168 //----------------------------------------
169 nw::gfx::Camera*
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)170 Utility::CreateFrustumCamera(
171 os::IAllocator* allocator,
172 const nw::math::VEC3& cameraPosition,
173 const nw::math::VEC3& targetPosition,
174 f32 nearClip,
175 f32 farClip,
176 const nw::math::VEC2& projectionCenter,
177 f32 projectionHeight,
178 nw::math::PivotDirection pivotDirection,
179 f32 wScale
180 )
181 {
182 NW_POINTER_ASSERT(allocator);
183
184 nw::gfx::LookAtTargetViewUpdater* viewUpdater =
185 nw::gfx::LookAtTargetViewUpdater::Create(allocator);
186 NW_POINTER_ASSERT(viewUpdater);
187
188 nw::gfx::ResLookAtTargetViewUpdater resViewUpdater =
189 nw::gfx::ResStaticCast<nw::gfx::ResLookAtTargetViewUpdater>(viewUpdater->GetResource());
190
191 resViewUpdater.SetTargetPosition(targetPosition);
192 resViewUpdater.SetUpwardVector(0.0f,1.0f,0.0f);
193
194 nw::gfx::FrustumProjectionUpdater* projectionUpdater =
195 nw::gfx::FrustumProjectionUpdater::Create(allocator);
196 NW_POINTER_ASSERT(projectionUpdater);
197
198 projectionUpdater->SetPivotDirection(pivotDirection);
199
200 nw::gfx::ResFrustumProjectionUpdater resProjectionUpdater =
201 nw::gfx::ResStaticCast<nw::gfx::ResFrustumProjectionUpdater>(
202 projectionUpdater->GetResource());
203 resProjectionUpdater.SetNear(nearClip);
204 resProjectionUpdater.SetFar(farClip);
205 nw::gfx::ResProjectionRect rect = resProjectionUpdater.GetRect();
206 rect.m_Center = projectionCenter;
207 rect.m_Height = projectionHeight;
208 resProjectionUpdater.SetRect(rect);
209
210 nw::gfx::Camera* camera =
211 nw::gfx::Camera::DynamicBuilder()
212 .MaxChildren(0)
213 .MaxCallbacks(0)
214 .ViewUpdater(viewUpdater)
215 .ProjectionUpdater(projectionUpdater)
216 .Create(allocator);
217
218 NW_POINTER_ASSERT(camera);
219
220 camera->Transform().SetTranslate(cameraPosition);
221 camera->SetWScale(wScale);
222
223 return camera;
224 }
225
226 //----------------------------------------
227 nw::gfx::Camera*
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)228 Utility::CreateOrthoCamera(
229 os::IAllocator* allocator,
230 const nw::math::VEC3& cameraPosition,
231 const nw::math::VEC3& targetPosition,
232 f32 nearClip,
233 f32 farClip,
234 const nw::math::VEC2& projectionCenter,
235 f32 projectionHeight,
236 nw::math::PivotDirection pivotDirection,
237 f32 wScale
238 )
239 {
240 NW_POINTER_ASSERT(allocator);
241
242 nw::gfx::LookAtTargetViewUpdater* viewUpdater =
243 nw::gfx::LookAtTargetViewUpdater::Create(allocator);
244 NW_POINTER_ASSERT(viewUpdater);
245
246 nw::gfx::ResLookAtTargetViewUpdater resViewUpdater =
247 nw::gfx::ResStaticCast<nw::gfx::ResLookAtTargetViewUpdater>(viewUpdater->GetResource());
248
249 resViewUpdater.SetTargetPosition(targetPosition);
250 resViewUpdater.SetUpwardVector(0.0f,1.0f,0.0f);
251
252 nw::gfx::OrthoProjectionUpdater* projectionUpdater =
253 nw::gfx::OrthoProjectionUpdater::Create(allocator);
254 NW_POINTER_ASSERT(projectionUpdater);
255
256 projectionUpdater->SetPivotDirection(pivotDirection);
257
258 nw::gfx::ResOrthoProjectionUpdater resProjectionUpdater =
259 nw::gfx::ResStaticCast<nw::gfx::ResOrthoProjectionUpdater>(
260 projectionUpdater->GetResource());
261 resProjectionUpdater.SetNear(nearClip);
262 resProjectionUpdater.SetFar(farClip);
263 nw::gfx::ResProjectionRect rect = resProjectionUpdater.GetRect();
264 rect.m_Center = projectionCenter;
265 rect.m_Height = projectionHeight;
266 resProjectionUpdater.SetRect(rect);
267
268 nw::gfx::Camera* camera =
269 nw::gfx::Camera::DynamicBuilder()
270 .MaxChildren(0)
271 .MaxCallbacks(0)
272 .ViewUpdater(viewUpdater)
273 .ProjectionUpdater(projectionUpdater)
274 .Create(allocator);
275
276 NW_POINTER_ASSERT(camera);
277
278 camera->Transform().SetTranslate(cameraPosition);
279 camera->SetWScale(wScale);
280
281 return camera;
282 }
283
284 //----------------------------------------
285 void
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)286 Utility::CreateStereoCameras(
287 nw::gfx::Camera** ppBaseCamera,
288 nw::gfx::Camera** ppLeftCamera,
289 nw::gfx::Camera** ppRightCamera,
290 os::IAllocator* allocator,
291 const nw::math::VEC3& cameraPosition,
292 const nw::math::VEC3& targetPosition,
293 f32 nearClip,
294 f32 farClip,
295 f32 fovyRadian,
296 f32 wScale
297 )
298 {
299 NW_POINTER_ASSERT(ppBaseCamera);
300 NW_POINTER_ASSERT(ppLeftCamera);
301 NW_POINTER_ASSERT(ppRightCamera);
302 NW_POINTER_ASSERT(allocator);
303
304 *ppBaseCamera = nw::demo::Utility::CreateCamera(
305 allocator,
306 cameraPosition,
307 targetPosition,
308 nearClip,
309 farClip,
310 fovyRadian,
311 nw::math::PIVOT_NONE
312 );
313 (*ppBaseCamera)->SetWScale(wScale);
314
315 *ppLeftCamera =
316 nw::gfx::Camera::DynamicBuilder()
317 .MaxChildren(0)
318 .MaxCallbacks(0)
319 .Create(allocator);
320
321 NW_POINTER_ASSERT(*ppLeftCamera);
322
323 (*ppLeftCamera)->SetWScale(wScale);
324
325 *ppRightCamera =
326 nw::gfx::Camera::DynamicBuilder()
327 .MaxChildren(0)
328 .MaxCallbacks(0)
329 .Create(allocator);
330
331 NW_POINTER_ASSERT(*ppRightCamera);
332
333 (*ppRightCamera)->SetWScale(wScale);
334 }
335
336
337 //----------------------------------------
338 void
SetCameraAspectRatio(nw::gfx::Camera * camera,f32 aspectRatio)339 Utility::SetCameraAspectRatio(
340 nw::gfx::Camera* camera,
341 f32 aspectRatio
342 )
343 {
344 NW_POINTER_ASSERT(camera);
345
346 f32 fovy;
347 f32 near;
348 f32 far;
349 camera->GetPerspective(&fovy, NULL, &near, &far);
350
351 camera->SetPerspective(fovy, aspectRatio, near, far);
352
353 camera->UpdateCameraMatrix();
354 }
355
356 //----------------------------------------
357 nw::gfx::IRenderTarget*
CreateUpperScreenBuffer(os::IAllocator * allocator,nw::demo::RenderSystem::Description & renderDescription)358 Utility::CreateUpperScreenBuffer(
359 os::IAllocator* allocator,
360 nw::demo::RenderSystem::Description& renderDescription
361 )
362 {
363 // オンスクリーンバッファは縦と横が逆になっているため、
364 // 幅と高さを逆に設定しています。
365 return nw::gfx::IRenderTarget::Builder()
366 .BufferSize(
367 renderDescription.upperScreenDescription.height,
368 renderDescription.upperScreenDescription.width
369 )
370 .ColorFormat(renderDescription.renderColorFormat)
371 .Create(allocator);
372 }
373
374 //----------------------------------------
375 nw::gfx::IRenderTarget*
CreateLowerScreenBuffer(os::IAllocator * allocator,nw::demo::RenderSystem::Description & renderDescription)376 Utility::CreateLowerScreenBuffer(
377 os::IAllocator* allocator,
378 nw::demo::RenderSystem::Description& renderDescription
379 )
380 {
381 // オンスクリーンバッファは縦と横が逆になっているため、
382 // 幅と高さを逆に設定しています。
383 return nw::gfx::IRenderTarget::Builder()
384 .BufferSize(
385 renderDescription.lowerScreenDescription.height,
386 renderDescription.lowerScreenDescription.width
387 )
388 .ColorFormat(renderDescription.renderColorFormat)
389 .Create(allocator);
390 }
391
392 //----------------------------------------
393 nw::gfx::SceneNode*
CreateSceneNode(os::IAllocator * deviceAllocator,nw::gfx::ResSceneObject resource,bool isAnimationEnabled,nw::gfx::Model::BufferOption bufferOption,s32 maxAnimObjects)394 Utility::CreateSceneNode(
395 os::IAllocator* deviceAllocator,
396 nw::gfx::ResSceneObject resource,
397 bool isAnimationEnabled,
398 nw::gfx::Model::BufferOption bufferOption,
399 s32 maxAnimObjects
400 )
401 {
402 nw::gfx::SceneObject* sceneObject = nw::gfx::SceneBuilder()
403 .Resource(resource)
404 .BufferOption(bufferOption)
405 .MaxAnimObjectsPerGroup(maxAnimObjects)
406 .IsAnimationEnabled(isAnimationEnabled)
407 .CreateObject(deviceAllocator, deviceAllocator);
408
409 nw::gfx::SceneNode* node = nw::ut::DynamicCast<nw::gfx::SceneNode*>(sceneObject);
410
411 return node;
412 }
413
414 //----------------------------------------
415 ut::MoveArray<u8>
LoadFile(os::IAllocator * allocator,const wchar_t * filePath,u32 align)416 Utility::LoadFile(
417 os::IAllocator* allocator,
418 const wchar_t* filePath,
419 u32 align /* = 32 */
420 )
421 {
422 nn::fs::FileReader fileReader;
423
424 nn::Result result = fileReader.TryInitialize(filePath);
425 if (result.IsFailure())
426 {
427 return nw::ut::MoveArray<u8>();
428 }
429 s32 fileSize = static_cast<s32>(fileReader.GetSize());
430
431 void* memory = allocator->Alloc(fileSize, static_cast<u8>(align));
432 nw::ut::MoveArray<u8> buffer(memory, fileSize, allocator);
433 buffer.resize(fileSize);
434
435 fileReader.Read(&buffer.front(), fileSize);
436
437 fileReader.Finalize();
438
439 // コンテナを返してますが、バッファはコピーされません。
440 // 所有権が移動します。
441 return buffer;
442 }
443
444 //----------------------------------------
445 nw::gfx::AnimGroup*
GetAnimGroup(nw::gfx::SceneObject * object,AnimationType animationType)446 Utility::GetAnimGroup(
447 nw::gfx::SceneObject* object,
448 AnimationType animationType
449 )
450 {
451 // アニメーショングループを取得します。
452 nw::gfx::AnimGroup* animGroup = NULL;
453
454 switch (animationType)
455 {
456 case SKELETAL_ANIMATION:
457 {
458 nw::gfx::SkeletalModel* skeletalModel = nw::ut::DynamicCast<nw::gfx::SkeletalModel*>(object);
459 NW_ASSERT(skeletalModel);
460 animGroup = skeletalModel->GetSkeletalAnimGroup();
461 }
462 break;
463 case MATERIAL_ANIMATION:
464 {
465 nw::gfx::Model* model = nw::ut::DynamicCast<nw::gfx::Model*>(object);
466 NW_ASSERT(model);
467 animGroup = model->GetMaterialAnimGroup();
468 }
469 break;
470 case VISIBILITY_ANIMATION:
471 {
472 nw::gfx::Model* model = nw::ut::DynamicCast<nw::gfx::Model*>(object);
473 NW_ASSERT(model);
474 animGroup = model->GetVisibilityAnimGroup();
475 }
476 break;
477 case CAMERA_ANIMATION:
478 {
479 nw::gfx::Camera* camera = nw::ut::DynamicCast<nw::gfx::Camera*>(object);
480 NW_ASSERT(camera);
481 animGroup = camera->GetAnimGroup();
482 }
483 break;
484 case LIGHT_ANIMATION:
485 {
486 nw::gfx::Light* light = nw::ut::DynamicCast<nw::gfx::Light*>(object);
487 NW_ASSERT(light);
488 animGroup = light->GetAnimGroup();
489 }
490 break;
491 default:
492 NW_FATAL_ERROR("Invalid animation type");
493 }
494
495 return animGroup;
496 }
497
498 //----------------------------------------
499 bool
BindAnimationObject(nw::gfx::SceneObject * object,nw::gfx::AnimObject * animObject,AnimationType animationType)500 Utility::BindAnimationObject(
501 nw::gfx::SceneObject* object,
502 nw::gfx::AnimObject* animObject,
503 AnimationType animationType
504 )
505 {
506 nw::gfx::AnimGroup* animGroup = GetAnimGroup(object, animationType);
507 if (!animGroup)
508 {
509 return false;
510 }
511
512 if (animObject->TryBind( animGroup ).IsFailure())
513 {
514 return false;
515 }
516
517 switch (animationType)
518 {
519 case SKELETAL_ANIMATION:
520 {
521 nw::gfx::SkeletalModel* skeletalModel = nw::ut::DynamicCast<nw::gfx::SkeletalModel*>(object);
522 NW_ASSERT(skeletalModel);
523 skeletalModel->SetSkeletalAnimObject(animObject);
524 }
525 break;
526 case MATERIAL_ANIMATION:
527 {
528 nw::gfx::Model* model = nw::ut::DynamicCast<nw::gfx::Model*>(object);
529 NW_ASSERT(model);
530 model->SetMaterialAnimObject(animObject);
531 }
532 break;
533 case VISIBILITY_ANIMATION:
534 {
535 nw::gfx::Model* model = nw::ut::DynamicCast<nw::gfx::Model*>(object);
536 NW_ASSERT(model);
537 model->SetVisibilityAnimObject(animObject);
538 }
539 break;
540 case CAMERA_ANIMATION:
541 {
542 nw::gfx::Camera* camera = nw::ut::DynamicCast<nw::gfx::Camera*>(object);
543 NW_ASSERT(camera);
544 camera->SetAnimObject(animObject);
545 }
546 break;
547 case LIGHT_ANIMATION:
548 {
549 nw::gfx::Light* light = nw::ut::DynamicCast<nw::gfx::Light*>(object);
550 NW_ASSERT(light);
551 light->SetAnimObject(animObject);
552 }
553 break;
554 default:
555 NW_FATAL_ERROR("Invalid animation type");
556 }
557
558 return true;
559 }
560
561
562 namespace internal {
563
564 //----------------------------------------
565 bool
IsTerminatingImpl()566 IsTerminatingImpl()
567 {
568 return false;
569 }
570
571 } // namespace internal
572
573 } /* namespace demo */
574 } /* namespace nw */
575