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