1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_RotateViewUpdater.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: 29651 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 #include <nw/gfx/gfx_RotateViewUpdater.h>
18 #include <nw/os/os_Memory.h>
19 
20 namespace nw
21 {
22 namespace gfx
23 {
24 
25 NW_UT_RUNTIME_TYPEINFO_DEFINITION(RotateViewUpdater, CameraViewUpdater);
26 
27 //----------------------------------------
28 RotateViewUpdater*
Create(os::IAllocator * allocator)29 RotateViewUpdater::Create(os::IAllocator* allocator)
30 {
31     NW_NULL_ASSERT(allocator);
32 
33     void* updaterMemory = allocator->Alloc(sizeof(RotateViewUpdater));
34     NW_NULL_ASSERT(updaterMemory);
35 
36     void* dataMemory
37         = AllocateAndFill<ResRotateViewUpdaterData>(allocator, 0);
38 
39     ResRotateViewUpdaterData* buffer =
40             new(dataMemory) ResRotateViewUpdaterData();
41 
42     buffer->typeInfo     = ResRotateViewUpdater::TYPE_INFO;
43     buffer->m_ViewRotate = VIEW_VIEW_ROTATE;
44     buffer->m_Flags      = 0x0;
45 
46     ResRotateViewUpdater resUpdater = ResRotateViewUpdater(buffer);
47 
48 
49     return new(updaterMemory) RotateViewUpdater(allocator, true, resUpdater);
50 }
51 
52 //----------------------------------------
53 RotateViewUpdater*
Create(os::IAllocator * allocator,ResRotateViewUpdater resUpdater)54 RotateViewUpdater::Create(os::IAllocator* allocator, ResRotateViewUpdater resUpdater)
55 {
56     NW_NULL_ASSERT(allocator);
57 
58     void* updaterMemory = allocator->Alloc(sizeof(RotateViewUpdater));
59     NW_NULL_ASSERT(updaterMemory);
60 
61     return new(updaterMemory) RotateViewUpdater(allocator, false, resUpdater);
62 }
63 
64 //----------------------------------------
RotateViewUpdater(os::IAllocator * allocator,bool isDynamic,ResRotateViewUpdater resUpdater)65 RotateViewUpdater::RotateViewUpdater(
66     os::IAllocator* allocator,
67     bool isDynamic,
68     ResRotateViewUpdater resUpdater
69 )
70 : CameraViewUpdater(allocator, isDynamic),
71   m_Resource(resUpdater)
72 {
73 }
74 
75 //----------------------------------------
~RotateViewUpdater()76 RotateViewUpdater::~RotateViewUpdater()
77 {
78     if (this->IsDynamic() && this->m_Resource.IsValid())
79     {
80         this->GetAllocator().Free(m_Resource.ptr());
81     }
82 }
83 
84 //----------------------------------------
85 void
Update(math::MTX34 * viewMatrix,const math::MTX34 & worldMatrix,const math::VEC3 & cameraPosition)86 RotateViewUpdater::Update(
87                                 math::MTX34* viewMatrix,
88                                 const math::MTX34& worldMatrix,
89                                 const math::VEC3& cameraPosition)
90 {
91     NW_ASSERT(m_Resource.IsValid());
92     u32 flags = m_Resource.GetFlags();
93     if (ut::CheckFlag(flags, ResRotateViewUpdaterData::FLAG_INHERITING_ROTATE))
94     {
95         math::MTX33 rotateMatrix;
96             math::MTX34ToMTX33(&rotateMatrix, &worldMatrix);
97 
98         math::VEC3 upwardVector(0.0f,1.0f,0.0f);
99         math::VEC3 targetPosition(0.0f,0.0f,-1.0f);
100 
101         // TODO: ZXY回転の最適化が必要。
102         math::MTX34 transformMatrix;
103         math::MTX34 rotateMatrixX;
104         math::MTX34 rotateMatrixY;
105         math::MTX34 rotateMatrixZ;
106         math::MTX34RotXYZRad(&rotateMatrixX, this->m_Resource.GetViewRotate().x, 0.0f, 0.0f);
107         math::MTX34RotXYZRad(&rotateMatrixY, 0.0f, this->m_Resource.GetViewRotate().y, 0.0f);
108         math::MTX34RotXYZRad(&rotateMatrixZ, 0.0f, 0.0f, this->m_Resource.GetViewRotate().z);
109 
110         math::MTX34Mult(&transformMatrix, &rotateMatrixY, &rotateMatrixX);
111         math::MTX34Mult(&transformMatrix, &transformMatrix, &rotateMatrixZ);
112 
113         math::VEC3Transform(&upwardVector, &transformMatrix, &upwardVector);
114         math::VEC3Transform(&upwardVector, &rotateMatrix, &upwardVector);
115 
116         math::VEC3Transform(&targetPosition, &transformMatrix, &targetPosition);
117         math::VEC3Transform(&targetPosition, &rotateMatrix, &targetPosition);
118         math::VEC3Add(&targetPosition, &targetPosition, &cameraPosition);
119 
120         math::MTX34LookAt(
121             viewMatrix,
122             &cameraPosition,
123             &upwardVector,
124             &targetPosition);
125     }
126     else
127     {
128         math::MTX34CameraRotateRad(viewMatrix, &cameraPosition, &this->m_Resource.GetViewRotate());
129     }
130 }
131 
132 } // namespace gfx
133 } // namespace nw
134