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