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