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