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