1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_RotateViewUpdater.cpp
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #include "precompiled.h"
19 #include <nw/gfx/gfx_RotateViewUpdater.h>
20 #include <nw/os/os_Memory.h>
21 
22 namespace nw
23 {
24 namespace gfx
25 {
26 
27 NW_UT_RUNTIME_TYPEINFO_DEFINITION(RotateViewUpdater, CameraViewUpdater);
28 
29 //----------------------------------------
30 RotateViewUpdater*
Create(os::IAllocator * allocator)31 RotateViewUpdater::Create(os::IAllocator* allocator)
32 {
33     NW_NULL_ASSERT(allocator);
34 
35     void* updaterMemory = allocator->Alloc(sizeof(RotateViewUpdater));
36     NW_NULL_ASSERT(updaterMemory);
37 
38     void* dataMemory
39         = AllocateAndFill<ResRotateViewUpdaterData>(allocator, 0);
40 
41     ResRotateViewUpdaterData* buffer =
42             new(dataMemory) ResRotateViewUpdaterData();
43 
44     buffer->typeInfo     = ResRotateViewUpdater::TYPE_INFO;
45     buffer->m_ViewRotate = VIEW_VIEW_ROTATE;
46     buffer->m_Flags      = 0x0;
47 
48     ResRotateViewUpdater resUpdater = ResRotateViewUpdater(buffer);
49 
50 
51     return new(updaterMemory) RotateViewUpdater(allocator, true, resUpdater);
52 }
53 
54 //----------------------------------------
55 RotateViewUpdater*
Create(os::IAllocator * allocator,ResRotateViewUpdater resUpdater)56 RotateViewUpdater::Create(os::IAllocator* allocator, ResRotateViewUpdater resUpdater)
57 {
58     NW_NULL_ASSERT(allocator);
59 
60     void* updaterMemory = allocator->Alloc(sizeof(RotateViewUpdater));
61     NW_NULL_ASSERT(updaterMemory);
62 
63     return new(updaterMemory) RotateViewUpdater(allocator, false, resUpdater);
64 }
65 
66 //----------------------------------------
RotateViewUpdater(os::IAllocator * allocator,bool isDynamic,ResRotateViewUpdater resUpdater)67 RotateViewUpdater::RotateViewUpdater(
68     os::IAllocator* allocator,
69     bool isDynamic,
70     ResRotateViewUpdater resUpdater
71 )
72 : CameraViewUpdater(allocator, isDynamic),
73   m_Resource(resUpdater)
74 {
75 }
76 
77 //----------------------------------------
~RotateViewUpdater()78 RotateViewUpdater::~RotateViewUpdater()
79 {
80     if (this->IsDynamic() && this->m_Resource.IsValid())
81     {
82         this->GetAllocator().Free(m_Resource.ptr());
83     }
84 }
85 
86 //----------------------------------------
87 void
Update(math::MTX34 * viewMatrix,const math::MTX34 & worldMatrix,const math::VEC3 & cameraPosition)88 RotateViewUpdater::Update(
89                                 math::MTX34* viewMatrix,
90                                 const math::MTX34& worldMatrix,
91                                 const math::VEC3& cameraPosition)
92 {
93     NW_ASSERT(m_Resource.IsValid());
94     u32 flags = m_Resource.GetFlags();
95     if (ut::CheckFlag(flags, ResRotateViewUpdaterData::FLAG_INHERITING_ROTATE))
96     {
97         math::MTX33 rotateMatrix;
98             math::MTX34ToMTX33(&rotateMatrix, &worldMatrix);
99 
100         math::VEC3 upwardVector(0.0f,1.0f,0.0f);
101         math::VEC3 targetPosition(0.0f,0.0f,-1.0f);
102 
103         // TODO: ZXY回転の最適化が必要。
104         math::MTX34 transformMatrix;
105         math::MTX34 rotateMatrixX;
106         math::MTX34 rotateMatrixY;
107         math::MTX34 rotateMatrixZ;
108         math::MTX34RotXYZRad(&rotateMatrixX, this->m_Resource.GetViewRotate().x, 0.0f, 0.0f);
109         math::MTX34RotXYZRad(&rotateMatrixY, 0.0f, this->m_Resource.GetViewRotate().y, 0.0f);
110         math::MTX34RotXYZRad(&rotateMatrixZ, 0.0f, 0.0f, this->m_Resource.GetViewRotate().z);
111 
112         math::MTX34Mult(&transformMatrix, &rotateMatrixY, &rotateMatrixX);
113         math::MTX34Mult(&transformMatrix, &transformMatrix, &rotateMatrixZ);
114 
115         math::VEC3Transform(&upwardVector, &transformMatrix, &upwardVector);
116         math::VEC3Transform(&upwardVector, &rotateMatrix, &upwardVector);
117 
118         math::VEC3Transform(&targetPosition, &transformMatrix, &targetPosition);
119         math::VEC3Transform(&targetPosition, &rotateMatrix, &targetPosition);
120         math::VEC3Add(&targetPosition, &targetPosition, &cameraPosition);
121 
122         math::MTX34LookAt(
123             viewMatrix,
124             &cameraPosition,
125             &upwardVector,
126             &targetPosition);
127     }
128     else
129     {
130         math::MTX34CameraRotateRad(viewMatrix, &cameraPosition, &this->m_Resource.GetViewRotate());
131     }
132 }
133 
134 } // namespace gfx
135 } // namespace nw
136