1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_SceneNode.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: 24950 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 
18 #include <nw/gfx/gfx_SceneNode.h>
19 #include <nw/gfx/gfx_ISceneVisitor.h>
20 
21 #include <nw/ut/ut_ResUtil.h>
22 #include <nw/ut/ut_ResDictionary.h>
23 #include <nw/ut/ut_Foreach.h>
24 
25 namespace nw
26 {
27 namespace gfx
28 {
29 
30 NW_UT_RUNTIME_TYPEINFO_DEFINITION(SceneNode, SceneObject);
31 
32 //----------------------------------------
33 SceneNode*
Create(os::IAllocator * allocator)34 SceneNode::DynamicBuilder::Create(
35     os::IAllocator* allocator
36 )
37 {
38     NW_NULL_ASSERT(allocator);
39 
40     void* memory = allocator->Alloc(sizeof(SceneNode));
41     NW_NULL_ASSERT(memory);
42 
43     SceneNode* node = new(memory) SceneNode(
44         allocator, ResSceneNode(), m_Description);
45 
46     Result result = node->Initialize(allocator);
47 
48     NW_ASSERT(result.IsSuccess());
49 
50     return node;
51 
52 }
53 
54 //----------------------------------------
55 SceneNode*
Create(SceneNode * parent,ResSceneObject resource,const SceneNode::Description & description,os::IAllocator * allocator)56 SceneNode::Create(
57     SceneNode* parent,
58     ResSceneObject resource,
59     const SceneNode::Description& description,
60     os::IAllocator* allocator
61 )
62 {
63     NW_NULL_ASSERT(allocator);
64 
65     ResSceneNode resNode = ResStaticCast<ResSceneNode>(resource);
66 
67     void* memory = allocator->Alloc(sizeof(SceneNode));
68     NW_NULL_ASSERT(memory);
69 
70     SceneNode* node = new(memory) SceneNode(
71         allocator, resNode, description);
72 
73     Result result = node->Initialize(allocator);
74 
75     NW_ASSERT(result.IsSuccess());
76 
77     if (parent)
78     {
79         bool isAttached = parent->AttachChild(node);
80         NW_ASSERT(isAttached);
81     }
82     return node;
83 }
84 
85 //----------------------------------------
86 void
Accept(ISceneVisitor * visitor)87 SceneNode::Accept(
88     ISceneVisitor* visitor
89 )
90 {
91     visitor->VisitSceneNode(this);
92     AcceptChildren(visitor);
93 }
94 
95 //----------------------------------------
96 Result
CreateAnimBinding(os::IAllocator * allocator)97 SceneNode::CreateAnimBinding(os::IAllocator* allocator)
98 {
99     Result result = INITIALIZE_RESULT_OK;
100 
101     if (!m_Description.isAnimationEnabled)
102     {
103         return result;
104     }
105 
106     ResSceneObject resSceneObject = GetResSceneObject();
107     ResSceneNode resSceneNode = *reinterpret_cast<ResSceneNode*>(&resSceneObject);
108     if(!resSceneNode.IsValid())
109     {
110         return result;
111     }
112 
113     const int animGroupCount = resSceneNode.GetAnimGroupsCount();
114     if (animGroupCount == 0)
115     {
116         return result;
117     }
118     AnimBinding* animBinding = AnimBinding::Builder()
119         .MaxAnimGroups(animGroupCount)
120         .MaxAnimObjectsPerGroup(m_Description.maxAnimObjectsPerGroup)
121         .Create(allocator);
122 
123     if (animBinding == NULL)
124     {
125         result |= Result::MASK_FAIL_BIT;
126     }
127 
128     NW_ENSURE_AND_RETURN(result);
129 
130     SetAnimBinding(animBinding);
131 
132     return result;
133 }
134 
135 //----------------------------------------
136 Result
CreateChildren(os::IAllocator * allocator)137 SceneNode::CreateChildren(os::IAllocator* allocator)
138 {
139     Result result = INITIALIZE_RESULT_OK;
140 
141     if (m_Description.isFixedSizeMemory)
142     {
143         if (m_Description.maxChildren == 0)
144         {
145             m_Children = SceneNodeChildren(NULL, NULL, 0, NULL);
146         }
147         else
148         {
149             void* memory = allocator->Alloc(
150                 sizeof(SceneNode*) * m_Description.maxChildren, CHILDREN_MEMORY_ALIGNMENT);
151 
152             if (memory == NULL)
153             {
154                 result |= Result::MASK_FAIL_BIT;
155             }
156             NW_ENSURE_AND_RETURN(result);
157 
158             m_Children = SceneNodeChildren(NULL, memory, m_Description.maxChildren, allocator);
159         }
160     }
161     else
162     {
163         m_Children = SceneNodeChildren(NULL, allocator);
164     }
165 
166     return result;
167 }
168 
169 //----------------------------------------
170 Result
CreateCallbacks(os::IAllocator * allocator)171 SceneNode::CreateCallbacks(os::IAllocator* allocator)
172 {
173     Result result = INITIALIZE_RESULT_OK;
174 
175     if (m_Description.isFixedSizeMemory)
176     {
177         if (m_Description.maxCallbacks == 0)
178         {
179             this->m_PreUpdateSignal =
180                 UpdateSignal::CreateInvalidateSignal(allocator);
181         }
182         else
183         {
184             this->m_PreUpdateSignal =
185                 UpdateSignal::CreateFixedSizedSignal(m_Description.maxCallbacks, allocator);
186         }
187     }
188     else
189     {
190         this->m_PreUpdateSignal =
191             UpdateSignal::CreateVariableSizeSignal(allocator);
192     }
193 
194     // 動的配列のメモリ確保に失敗した場合
195     if (m_PreUpdateSignal == NULL)
196     {
197         result |= Result::MASK_FAIL_BIT;
198     }
199 
200     return result;
201 }
202 
203 //----------------------------------------
204 Result
Initialize(os::IAllocator * allocator)205 SceneNode::Initialize(os::IAllocator* allocator)
206 {
207     Result result = INITIALIZE_RESULT_OK;
208 
209     result |= CreateChildren(allocator);
210     NW_ENSURE_AND_RETURN(result);
211 
212     this->m_Children.SetParent(this);
213 
214     result |= CreateCallbacks(allocator);
215     NW_ENSURE_AND_RETURN(result);
216 
217     result |= CreateAnimBinding(allocator);
218     NW_ENSURE_AND_RETURN(result);
219 
220     return result;
221 }
222 
223 } // namespace gfx
224 } // namespace nw
225