1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_LookAtTargetViewUpdater.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: 18194 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17 #include <nw/gfx/gfx_LookAtTargetViewUpdater.h>
18 #include <nw/os/os_Memory.h>
19
20 namespace nw
21 {
22 namespace gfx
23 {
24
25 NW_UT_RUNTIME_TYPEINFO_DEFINITION(LookAtTargetViewUpdater, CameraViewUpdater);
26
27 //----------------------------------------
28 LookAtTargetViewUpdater*
Create(os::IAllocator * allocator)29 LookAtTargetViewUpdater::Create(os::IAllocator* allocator)
30 {
31 NW_NULL_ASSERT(allocator);
32
33 void* updaterMemory = allocator->Alloc(sizeof(LookAtTargetViewUpdater));
34 NW_NULL_ASSERT(updaterMemory);
35
36 void* dataMemory
37 = allocator->AllocAndFill(sizeof(ResLookAtTargetViewUpdaterData), NULL);
38
39 ResLookAtTargetViewUpdaterData* buffer =
40 new(dataMemory) ResLookAtTargetViewUpdaterData();
41
42 buffer->typeInfo = ResLookAtTargetViewUpdater::TYPE_INFO;
43 buffer->m_TargetPosition = VIEW_TARGET_POSITION;
44 buffer->m_UpwardVector = VIEW_UPWARD_VECTOR;
45 buffer->m_Flags = 0x0;
46
47 ResLookAtTargetViewUpdater resUpdater = ResLookAtTargetViewUpdater(buffer);
48
49 return new(updaterMemory) LookAtTargetViewUpdater(allocator, true, resUpdater);
50 }
51
52 //----------------------------------------
53 LookAtTargetViewUpdater*
Create(os::IAllocator * allocator,ResLookAtTargetViewUpdater resUpdater)54 LookAtTargetViewUpdater::Create(os::IAllocator* allocator, ResLookAtTargetViewUpdater resUpdater)
55 {
56 NW_NULL_ASSERT(allocator);
57
58 void* updaterMemory = allocator->Alloc(sizeof(LookAtTargetViewUpdater));
59 NW_NULL_ASSERT(updaterMemory);
60
61 return new(updaterMemory) LookAtTargetViewUpdater(allocator, false, resUpdater);
62 }
63
64 //----------------------------------------
LookAtTargetViewUpdater(os::IAllocator * allocator,bool isDynamic,ResLookAtTargetViewUpdater resUpdater)65 LookAtTargetViewUpdater::LookAtTargetViewUpdater(
66 os::IAllocator* allocator,
67 bool isDynamic,
68 ResLookAtTargetViewUpdater resUpdater)
69 : CameraViewUpdater(allocator, isDynamic),
70 m_Resource(resUpdater)
71 {
72 }
73
74 //----------------------------------------
~LookAtTargetViewUpdater()75 LookAtTargetViewUpdater::~LookAtTargetViewUpdater()
76 {
77 if (this->IsDynamic() && this->m_Resource.IsValid())
78 {
79 this->GetAllocator().Free(m_Resource.ptr());
80 }
81 }
82
83 //----------------------------------------
84 void
Update(math::MTX34 * viewMatrix,const math::MTX34 & worldMatrix,const math::VEC3 & cameraPosition)85 LookAtTargetViewUpdater::Update(
86 math::MTX34* viewMatrix,
87 const math::MTX34& worldMatrix,
88 const math::VEC3& cameraPosition)
89 {
90 NW_ASSERT(m_Resource.IsValid());
91
92 u32 flags = m_Resource.GetFlags();
93 math::VEC3 targetPosition(this->m_Resource.GetTargetPosition());
94 math::VEC3 upwardVector(this->m_Resource.GetUpwardVector());
95
96 if (ut::CheckFlagOr(
97 flags,
98 ResLookAtTargetViewUpdaterData::FLAG_INHERITING_TARGET_ROTATE |
99 ResLookAtTargetViewUpdaterData::FLAG_INHERITING_TARGET_TRANSLATE |
100 ResLookAtTargetViewUpdaterData::FLAG_INHERITING_UP_ROTATE))
101 {
102 math::MTX33 rotateMatrix;
103 math::MTX34ToMTX33(&rotateMatrix, &worldMatrix);
104
105 if (ut::CheckFlag(flags, ResLookAtTargetViewUpdaterData::FLAG_INHERITING_UP_ROTATE))
106 {
107 math::VEC3Transform(&upwardVector, &rotateMatrix, &upwardVector);
108 }
109 if (ut::CheckFlag(flags, ResLookAtTargetViewUpdaterData::FLAG_INHERITING_TARGET_ROTATE))
110 {
111 math::VEC3Transform(&targetPosition, &rotateMatrix, &targetPosition);
112 }
113 if (ut::CheckFlag(flags, ResLookAtTargetViewUpdaterData::FLAG_INHERITING_TARGET_TRANSLATE))
114 {
115 math::VEC3Add(&targetPosition, &targetPosition, &cameraPosition);
116 }
117 }
118
119 NW_ASSERT(cameraPosition != targetPosition);
120 NW_ASSERT(!upwardVector.IsZero());
121
122 // 視線ベクトルとアップベクトルが平行ではいけない
123 NW_ASSERT(!math::VEC3().Cross(upwardVector, targetPosition - cameraPosition).IsZero());
124
125 math::MTX34LookAt(
126 viewMatrix,
127 &cameraPosition,
128 &upwardVector,
129 &targetPosition);
130 }
131
132 } // namespace gfx
133 } // namespace nw
134