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