1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_AimTargetViewUpdater.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_AimTargetViewUpdater.h>
18 #include <nw/os/os_Memory.h>
19
20 namespace nw
21 {
22 namespace gfx
23 {
24
25 NW_UT_RUNTIME_TYPEINFO_DEFINITION(AimTargetViewUpdater, CameraViewUpdater);
26
27 //----------------------------------------
28 AimTargetViewUpdater*
Create(os::IAllocator * allocator)29 AimTargetViewUpdater::Create(os::IAllocator* allocator)
30 {
31 NW_NULL_ASSERT(allocator);
32
33 void* updaterMemory = allocator->Alloc(sizeof(AimTargetViewUpdater));
34 NW_NULL_ASSERT(updaterMemory);
35
36 void* dataMemory
37 = allocator->AllocAndFill(sizeof(ResAimTargetViewUpdaterData), NULL);
38
39 ResAimTargetViewUpdaterData* buffer =
40 new(dataMemory) ResAimTargetViewUpdaterData();
41
42 buffer->typeInfo = ResAimTargetViewUpdater::TYPE_INFO;
43 buffer->m_TargetPosition = VIEW_TARGET_POSITION;
44 buffer->m_Twist = VIEW_TWIST;
45 buffer->m_Flags = 0x0;
46
47 ResAimTargetViewUpdater resUpdater = ResAimTargetViewUpdater(buffer);
48
49 return new(updaterMemory) AimTargetViewUpdater(allocator, true, resUpdater);
50 }
51
52 //----------------------------------------
53 AimTargetViewUpdater*
Create(os::IAllocator * allocator,ResAimTargetViewUpdater resUpdater)54 AimTargetViewUpdater::Create(
55 os::IAllocator* allocator,
56 ResAimTargetViewUpdater resUpdater)
57 {
58 NW_NULL_ASSERT(allocator);
59
60 void* updaterMemory = allocator->Alloc(sizeof(AimTargetViewUpdater));
61 NW_NULL_ASSERT(updaterMemory);
62
63 return new(updaterMemory) AimTargetViewUpdater(allocator, false, resUpdater);
64 }
65
66 //----------------------------------------
AimTargetViewUpdater(os::IAllocator * allocator,bool isDynamic,ResAimTargetViewUpdater resUpdater)67 AimTargetViewUpdater::AimTargetViewUpdater(
68 os::IAllocator* allocator,
69 bool isDynamic,
70 ResAimTargetViewUpdater resUpdater
71 )
72 : CameraViewUpdater(allocator, isDynamic),
73 m_Resource(resUpdater)
74 {
75 }
76
77 //----------------------------------------
~AimTargetViewUpdater()78 AimTargetViewUpdater::~AimTargetViewUpdater()
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 AimTargetViewUpdater::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
96 if (ut::CheckFlagOr(
97 flags,
98 ResAimTargetViewUpdaterData::FLAG_INHERITING_TARGET_TRANSLATE |
99 ResAimTargetViewUpdaterData::FLAG_INHERITING_TARGET_ROTATE))
100 {
101 // カメラ座標系のZ方向
102 math::VEC3 lookReverse(
103 cameraPosition.x - this->m_Resource.GetTargetPosition().x,
104 cameraPosition.y - this->m_Resource.GetTargetPosition().y,
105 cameraPosition.z - this->m_Resource.GetTargetPosition().z);
106
107 if ((lookReverse.x == 0.0f) && (lookReverse.z == 0.0f))
108 {
109 // こちらはcameraPosition == targetPositionでも問題ない
110 math::MTX34LookAtRad(viewMatrix, &cameraPosition, this->m_Resource.GetTwist(), &this->m_Resource.GetTargetPosition());
111 }
112 else
113 {
114 math::MTX33 rotateMatrix;
115 math::MTX34ToMTX33(&rotateMatrix, &worldMatrix);
116 // カメラ座標系のX方向
117 math::VEC3 r(lookReverse.z, 0.0f, -lookReverse.x);
118
119 math::VEC3Normalize(&lookReverse, &lookReverse);
120 math::VEC3Normalize(&r, &r);
121
122 // カメラ座標系のY方向
123 math::VEC3 u;
124 math::VEC3Cross(&u, &lookReverse, &r);
125
126 f32 st, ct;
127 math::SinCosRad(&st, &ct, this->m_Resource.GetTwist());
128 math::VEC3 up;
129
130 up.x = ct * u.x - st * r.x;
131 up.y = ct * u.y;
132 up.z = ct * u.z - st * r.z;
133
134 math::VEC3 targetPosition(this->m_Resource.GetTargetPosition());
135
136 if (ut::CheckFlag(flags, ResAimTargetViewUpdaterData::FLAG_INHERITING_TARGET_ROTATE))
137 {
138 math::VEC3Transform(&targetPosition, &rotateMatrix, &targetPosition);
139 math::VEC3Transform(&up, &rotateMatrix, &up);
140 }
141 if (ut::CheckFlag(flags, ResAimTargetViewUpdaterData::FLAG_INHERITING_TARGET_TRANSLATE))
142 {
143 math::VEC3Add(&targetPosition, &targetPosition, &cameraPosition);
144 }
145
146 NW_ASSERT(cameraPosition != targetPosition);
147
148 math::MTX34LookAt(
149 viewMatrix,
150 &cameraPosition,
151 &up,
152 &targetPosition);
153 }
154 }
155 else
156 {
157 // こちらはcameraPosition == targetPositionでも問題ない
158 math::MTX34LookAtRad(viewMatrix, &cameraPosition, this->m_Resource.GetTwist(), &this->m_Resource.GetTargetPosition());
159 }
160 }
161
162 } // namespace gfx
163 } // namespace nw
164