1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: anim_AnimBlend.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
20 #include <nw/anim/anim_AnimBlend.h>
21 #include <nw/ut/ut_Color.h>
22
23 namespace nw {
24 namespace anim {
25
26 //----------------------------------------------------------
27 bool
Blend(AnimResult * dst,float *,const AnimResult * src,const float *) const28 AnimBlendOpBool::Blend(
29 AnimResult* dst,
30 float* /*dstWeights*/,
31 const AnimResult* src,
32 const float* /*srcWeights*/
33 ) const
34 {
35 bool* dstPtr = reinterpret_cast<bool*>(dst->GetValueBuffer());
36 const bool* srcPtr = reinterpret_cast<const bool*>(src->GetValueBuffer());
37 if (dst->IsEnabledFlags(VALID_SINGLE))
38 {
39 *dstPtr = *dstPtr | *srcPtr; // 重みは使用しないで OR をとる
40 }
41 else
42 {
43 *dstPtr = *srcPtr;
44 dst->EnableFlags(VALID_SINGLE);
45 }
46 return !*dstPtr; // dst が true になった時点でブレンド処理のループを終了
47 }
48
49 //----------------------------------------------------------
50 bool
Blend(AnimResult * dst,float *,const AnimResult * src,const float * srcWeights) const51 AnimBlendOpFloat::Blend(
52 AnimResult* dst,
53 float* /*dstWeights*/,
54 const AnimResult* src,
55 const float* srcWeights
56 ) const
57 {
58 float* dstPtr = reinterpret_cast<float*>(dst->GetValueBuffer());
59 const float* srcPtr = reinterpret_cast<const float*>(src->GetValueBuffer());
60 const float weightedSrc = srcWeights[0] * (*srcPtr);
61 if (dst->IsEnabledFlags(VALID_SINGLE))
62 {
63 *dstPtr += weightedSrc;
64 }
65 else
66 {
67 *dstPtr = weightedSrc;
68 dst->EnableFlags(VALID_SINGLE);
69 }
70 return true;
71 }
72
73 //----------------------------------------------------------
74 bool
BlendFloatVector(AnimResult * dst,const AnimResult * src,float srcWeight,int compCount) const75 AnimBlendOp::BlendFloatVector(
76 AnimResult* dst,
77 const AnimResult* src,
78 float srcWeight,
79 int compCount
80 ) const
81 {
82 float* dstValues = reinterpret_cast<float*>(dst->GetValueBuffer());
83 const float* srcValues =
84 reinterpret_cast<const float*>(src->GetValueBuffer());
85
86 bit32 compFlag = VALID_X;
87 for (int compIdx = 0; compIdx < compCount; ++compIdx)
88 {
89 if (src->IsEnabledFlags(compFlag))
90 {
91 const float weightedSrc = srcWeight * srcValues[compIdx];
92 if (dst->IsEnabledFlags(compFlag))
93 {
94 dstValues[compIdx] += weightedSrc;
95 }
96 else
97 {
98 dstValues[compIdx] = weightedSrc;
99 dst->EnableFlags(compFlag);
100 }
101 }
102 compFlag <<= 1;
103 }
104 return true;
105 }
106
107 //----------------------------------------------------------
108 bool
OverrideFloatVector(AnimResult * dst,const AnimResult * src,int compCount,bit32 allCompValidFlag) const109 AnimBlendOp::OverrideFloatVector(
110 AnimResult* dst,
111 const AnimResult* src,
112 int compCount,
113 bit32 allCompValidFlag
114 ) const
115 {
116 float* dstValues = reinterpret_cast<float*>(dst->GetValueBuffer());
117 const float* srcValues =
118 reinterpret_cast<const float*>(src->GetValueBuffer());
119 bit32 dstFlags = dst->GetFlags();
120 const bit32 srcFlags = src->GetFlags();
121
122 bit32 compFlag = VALID_X;
123 for (int compIdx = 0; compIdx < compCount; ++compIdx)
124 {
125 if (~dstFlags & srcFlags & compFlag) // !(dstFlags & compFlag) && (srcFlags & compFlag)
126 {
127 dstValues[compIdx] = srcValues[compIdx];
128 dstFlags |= compFlag;
129 }
130 compFlag <<= 1;
131 }
132 dst->SetFlags(dstFlags);
133 return ((dstFlags & allCompValidFlag) == allCompValidFlag);
134 }
135
136 //----------------------------------------------------------
137 void
ApplyFloatVector(void * target,const AnimResult * result,int compCount) const138 AnimBlendOp::ApplyFloatVector(void* target, const AnimResult* result, int compCount) const
139 {
140 float* dstValues = reinterpret_cast<float*>(target);
141 const float* srcValues =
142 reinterpret_cast<const float*>(result->GetValueBuffer());
143
144 bit32 compFlag = VALID_X;
145 for (int compIdx = 0; compIdx < compCount; ++compIdx)
146 {
147 if (result->IsEnabledFlags(compFlag))
148 {
149 dstValues[compIdx] = srcValues[compIdx];
150 }
151 compFlag <<= 1;
152 }
153 }
154
155 //----------------------------------------------------------
156 void
ConvertFloatVectorToAnimResult(AnimResult * result,const void * source,int compCount) const157 AnimBlendOp::ConvertFloatVectorToAnimResult(
158 AnimResult* result,
159 const void* source,
160 int compCount
161 ) const
162 {
163 float* dstValues = reinterpret_cast<float*>(result->GetValueBuffer());
164 const float* srcValues =
165 reinterpret_cast<const float*>(source);
166
167 result->DisableFlags(VALID_XYZW);
168
169 bit32 compFlag = VALID_X;
170 for (int compIdx = 0; compIdx < compCount; ++compIdx)
171 {
172 result->EnableFlags(compFlag);
173 dstValues[compIdx] = srcValues[compIdx];
174 compFlag <<= 1;
175 }
176 }
177
178 //----------------------------------------------------------
179 bool
Blend(AnimResult * dst,float *,const AnimResult * src,const float * srcWeights) const180 AnimBlendOpRgbaColor::Blend(
181 AnimResult* dst,
182 float* /*dstWeights*/,
183 const AnimResult* src,
184 const float* srcWeights
185 ) const
186 {
187 NW_ASSERT(src->GetFlags() & VALID_RGBA); // 少なくとも 1 つの成分が有効である必要があります。
188 float* dstColor =
189 reinterpret_cast<ut::ResFloatColor*>(dst->GetValueBuffer())->ToArray();
190 const float* srcColor =
191 reinterpret_cast<const ut::ResFloatColor*>(src->GetValueBuffer())->ToArray();
192
193 bit32 compFlag = VALID_R;
194 for (int compIdx = 0; compIdx < COMPONENT_COUNT; ++compIdx)
195 {
196 if (src->IsEnabledFlags(compFlag))
197 {
198 const float weightedSrc = srcWeights[0] * srcColor[compIdx];
199 if (dst->IsEnabledFlags(compFlag))
200 {
201 dstColor[compIdx] += weightedSrc;
202 }
203 else
204 {
205 dstColor[compIdx] = weightedSrc;
206 dst->EnableFlags(compFlag);
207 }
208 }
209 compFlag <<= 1;
210 }
211 return true;
212 }
213
214 //----------------------------------------------------------
215 bool
Override(AnimResult * dst,const AnimResult * src) const216 AnimBlendOpRgbaColor::Override(AnimResult* dst, const AnimResult* src) const
217 {
218 NW_ASSERT(src->GetFlags() & VALID_RGBA); // 少なくとも 1 つの成分が有効である必要があります。
219 float* dstColor =
220 reinterpret_cast<ut::ResFloatColor*>(dst->GetValueBuffer())->ToArray();
221 const float* srcColor =
222 reinterpret_cast<const ut::ResFloatColor*>(src->GetValueBuffer())->ToArray();
223 bit32 dstFlags = dst->GetFlags();
224 const bit32 srcFlags = src->GetFlags();
225
226 bit32 compFlag = VALID_R;
227 for (int compIdx = 0; compIdx < COMPONENT_COUNT; ++compIdx)
228 {
229 if (~dstFlags & srcFlags & compFlag) // !(dstFlags & compFlag) && (srcFlags & compFlag)
230 {
231 dstColor[compIdx] = srcColor[compIdx];
232 dstFlags |= compFlag;
233 }
234 compFlag <<= 1;
235 }
236 dst->SetFlags(dstFlags);
237 return ((dstFlags & VALID_RGBA) == VALID_RGBA);
238 }
239
240 //----------------------------------------------------------
241 void
Apply(void * target,const AnimResult * result) const242 AnimBlendOpRgbaColor::Apply(void* target, const AnimResult* result) const
243 {
244 float* dstColor = reinterpret_cast<ut::ResFloatColor*>(target)->ToArray();
245 const float* srcColor =
246 reinterpret_cast<const ut::ResFloatColor*>(result->GetValueBuffer())->ToArray();
247
248 bit32 compFlag = VALID_R;
249 for (int compIdx = 0; compIdx < COMPONENT_COUNT; ++compIdx)
250 {
251 if (result->IsEnabledFlags(compFlag))
252 {
253 dstColor[compIdx] = srcColor[compIdx];
254 }
255 compFlag <<= 1;
256 }
257 }
258
259 //----------------------------------------------------------
260 void
ConvertToAnimResult(AnimResult * result,const void * source) const261 AnimBlendOpRgbaColor::ConvertToAnimResult(AnimResult* result, const void* source) const
262 {
263 float* dstColor = reinterpret_cast<ut::ResFloatColor*>(result->GetValueBuffer())->ToArray();
264 const float* srcColor =
265 reinterpret_cast<const ut::ResFloatColor*>(source)->ToArray();
266
267 result->DisableFlags(VALID_RGBA);
268
269 bit32 compFlag = VALID_R;
270 for (int compIdx = 0; compIdx < COMPONENT_COUNT; ++compIdx)
271 {
272 result->EnableFlags(compFlag);
273 dstColor[compIdx] = srcColor[compIdx];
274 compFlag <<= 1;
275 }
276 }
277
278 } // namespace anim
279 } // namespace nw
280