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