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