diff options
author | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 |
commit | 15740faf9fe9fe4be08965098bbf2947e096aeeb (patch) | |
tree | a730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/mecanim/generic/valuearray.cpp |
Diffstat (limited to 'Runtime/mecanim/generic/valuearray.cpp')
-rw-r--r-- | Runtime/mecanim/generic/valuearray.cpp | 925 |
1 files changed, 925 insertions, 0 deletions
diff --git a/Runtime/mecanim/generic/valuearray.cpp b/Runtime/mecanim/generic/valuearray.cpp new file mode 100644 index 0000000..e7bfb58 --- /dev/null +++ b/Runtime/mecanim/generic/valuearray.cpp @@ -0,0 +1,925 @@ +#include "UnityPrefix.h" +#include "Runtime/mecanim/generic/valuearray.h" + +#include "Runtime/Math/Simd/float4.h" +#include "Runtime/Math/Simd/bool4.h" +#include "Runtime/Math/Simd/xform.h" + +namespace mecanim +{ + template<typename TYPE> + static void ValueCopy(TYPE const * RESTRICT source, TYPE * RESTRICT destination, uint32_t sourceIndex, uint32_t destinationIndex) + { + destination[destinationIndex] = source[sourceIndex]; + } + + template<typename TYPE> + static void ValueArrayCopy(TYPE const * RESTRICT source, TYPE * RESTRICT destination, uint32_t sourceCount, uint32_t destinationCount) + { + sourceCount = min (destinationCount, sourceCount); + + uint32_t i; + for(i = 0; i < sourceCount; ++i) + { + destination[i] = source[i]; + } + } + + template<typename TYPE> + static void ValueArrayCopyMask(TYPE const * RESTRICT source, TYPE * RESTRICT destination, const bool* RESTRICT mask, uint32_t sourceCount) + { + uint32_t i; + for(i = 0; i < sourceCount; ++i) + { + if (mask[i]) + destination[i] = source[i]; + } + } + + void SetupValueArrayConstant(ValueArrayConstant* cst, ValueType aType, uint32_t aCount, memory::Allocator& alloc) + { + cst->m_Count = aCount; + cst->m_ValueArray = alloc.ConstructArray<ValueConstant>(cst->m_Count); + + uint32_t i; + for(i=0;i<aCount;++i) + { + cst->m_ValueArray[i].m_Type = aType; + cst->m_ValueArray[i].m_Index = i; + } + } + + ValueArrayConstant* CreateValueArrayConstant(uint32_t* apTypeArray, uint32_t aCount, memory::Allocator& alloc) + { + SETPROFILERLABEL(ValueArrayConstant); + + ValueArrayConstant* cst = alloc.Construct<ValueArrayConstant>(); + + cst->m_Count = aCount; + cst->m_ValueArray = alloc.ConstructArray<ValueConstant>(cst->m_Count); + + uint32_t positionCount = 0; + uint32_t quaternionCount = 0; + uint32_t scaleCount = 0; + uint32_t floatCount = 0; + uint32_t intCount = 0; + uint32_t boolCount = 0; + + uint32_t i; + for(i=0;i<aCount;++i) + { + cst->m_ValueArray[i].m_Type = apTypeArray[i]; + + switch(apTypeArray[i]) + { + case kPositionType: cst->m_ValueArray[i].m_Index = positionCount++; break; + case kQuaternionType: cst->m_ValueArray[i].m_Index = quaternionCount++; break; + case kScaleType: cst->m_ValueArray[i].m_Index = scaleCount++; break; + case kFloatType: cst->m_ValueArray[i].m_Index = floatCount++; break; + case kInt32Type: cst->m_ValueArray[i].m_Index = intCount++; break; + case kTriggerType: + case kBoolType: cst->m_ValueArray[i].m_Index = boolCount++; break; + default: assert(false); break; + } + } + return cst; + } + + ValueArrayConstant* CreateValueArrayConstant(ValueType aType, uint32_t aCount, memory::Allocator& alloc) + { + + SETPROFILERLABEL(ValueArrayConstant); + ValueArrayConstant* cst = alloc.Construct<ValueArrayConstant>(); + + SetupValueArrayConstant(cst, aType, aCount, alloc); + return cst; + } + + ValueArrayConstant* CreateValueArrayConstantCopy (const ValueArrayConstant* sourceConstant, uint32_t count, memory::Allocator& alloc) + { + + SETPROFILERLABEL(ValueArrayConstant); + + Assert(count <= sourceConstant->m_Count); + + ValueArrayConstant* cst = alloc.Construct<ValueArrayConstant>(); + cst->m_Count = count; + cst->m_ValueArray = alloc.ConstructArray<ValueConstant>(sourceConstant->m_ValueArray.Get(), count); + + return cst; + } + + + void DestroyValueArrayConstant(ValueArrayConstant * apCst, memory::Allocator& alloc) + { + if(apCst) + { + alloc.Deallocate(apCst->m_ValueArray); + alloc.Deallocate(apCst); + } + } + + void SetValueMask(ValueArrayMask *valueArrayMask, bool value) + { + for(int i = 0; i < valueArrayMask->m_PositionCount; i++) + valueArrayMask->m_PositionValues[i] = value; + + for(int i = 0; i < valueArrayMask->m_QuaternionCount; i++) + valueArrayMask->m_QuaternionValues[i] = value; + + for(int i = 0; i < valueArrayMask->m_ScaleCount; i++) + valueArrayMask->m_ScaleValues[i] = value; + + for(int i = 0; i < valueArrayMask->m_FloatCount; i++) + valueArrayMask->m_FloatValues[i] = value; + + for(int i = 0; i < valueArrayMask->m_IntCount; i++) + valueArrayMask->m_IntValues[i] = value; + } + + void CopyValueMask(ValueArrayMask *valueArrayMask,ValueArrayMask const *srcValueArrayMask) + { + for(int i = 0; i < valueArrayMask->m_PositionCount; i++) + valueArrayMask->m_PositionValues[i] = srcValueArrayMask->m_PositionValues[i]; + + for(int i = 0; i < valueArrayMask->m_QuaternionCount; i++) + valueArrayMask->m_QuaternionValues[i] = srcValueArrayMask->m_QuaternionValues[i]; + + for(int i = 0; i < valueArrayMask->m_ScaleCount; i++) + valueArrayMask->m_ScaleValues[i] = srcValueArrayMask->m_ScaleValues[i]; + + for(int i = 0; i < valueArrayMask->m_FloatCount; i++) + valueArrayMask->m_FloatValues[i] = srcValueArrayMask->m_FloatValues[i]; + + for(int i = 0; i < valueArrayMask->m_IntCount; i++) + valueArrayMask->m_IntValues[i] = srcValueArrayMask->m_IntValues[i]; + } + + void OrValueMask(ValueArrayMask *valueArrayMask,ValueArrayMask const *srcValueArrayMask) + { + for(int i = 0; i < valueArrayMask->m_PositionCount; i++) + valueArrayMask->m_PositionValues[i] = valueArrayMask->m_PositionValues[i] || srcValueArrayMask->m_PositionValues[i]; + + for(int i = 0; i < valueArrayMask->m_QuaternionCount; i++) + valueArrayMask->m_QuaternionValues[i] = valueArrayMask->m_QuaternionValues[i] || srcValueArrayMask->m_QuaternionValues[i]; + + for(int i = 0; i < valueArrayMask->m_ScaleCount; i++) + valueArrayMask->m_ScaleValues[i] = valueArrayMask->m_ScaleValues[i] || srcValueArrayMask->m_ScaleValues[i]; + + for(int i = 0; i < valueArrayMask->m_FloatCount; i++) + valueArrayMask->m_FloatValues[i] = valueArrayMask->m_FloatValues[i] || srcValueArrayMask->m_FloatValues[i]; + + for(int i = 0; i < valueArrayMask->m_IntCount; i++) + valueArrayMask->m_IntValues[i] = valueArrayMask->m_IntValues[i] || srcValueArrayMask->m_IntValues[i]; + } + + void AndValueMask(ValueArrayMask *valueArrayMask,ValueArrayMask const *srcValueArrayMask) + { + for(int i = 0; i < valueArrayMask->m_PositionCount; i++) + valueArrayMask->m_PositionValues[i] = valueArrayMask->m_PositionValues[i] && srcValueArrayMask->m_PositionValues[i]; + + for(int i = 0; i < valueArrayMask->m_QuaternionCount; i++) + valueArrayMask->m_QuaternionValues[i] = valueArrayMask->m_QuaternionValues[i] && srcValueArrayMask->m_QuaternionValues[i]; + + for(int i = 0; i < valueArrayMask->m_ScaleCount; i++) + valueArrayMask->m_ScaleValues[i] = valueArrayMask->m_ScaleValues[i] && srcValueArrayMask->m_ScaleValues[i]; + + for(int i = 0; i < valueArrayMask->m_FloatCount; i++) + valueArrayMask->m_FloatValues[i] = valueArrayMask->m_FloatValues[i] && srcValueArrayMask->m_FloatValues[i]; + + for(int i = 0; i < valueArrayMask->m_IntCount; i++) + valueArrayMask->m_IntValues[i] = valueArrayMask->m_IntValues[i] && srcValueArrayMask->m_IntValues[i]; + } + + void InvertValueMask(ValueArrayMask *valueArrayMask) + { + for(int i = 0; i < valueArrayMask->m_PositionCount; i++) + valueArrayMask->m_PositionValues[i] = !valueArrayMask->m_PositionValues[i]; + + for(int i = 0; i < valueArrayMask->m_QuaternionCount; i++) + valueArrayMask->m_QuaternionValues[i] = !valueArrayMask->m_QuaternionValues[i]; + + for(int i = 0; i < valueArrayMask->m_ScaleCount; i++) + valueArrayMask->m_ScaleValues[i] = !valueArrayMask->m_ScaleValues[i]; + + for(int i = 0; i < valueArrayMask->m_FloatCount; i++) + valueArrayMask->m_FloatValues[i] = !valueArrayMask->m_FloatValues[i]; + + for(int i = 0; i < valueArrayMask->m_IntCount; i++) + valueArrayMask->m_IntValues[i] = !valueArrayMask->m_IntValues[i]; + } + + ValueArrayMask* CreateValueArrayMask(ValueArrayConstant const* constant, memory::Allocator& alloc) + { + SETPROFILERLABEL(ValueArrayMask); + ValueArrayMask* valueArrayMask = alloc.Construct<ValueArrayMask>(); + + uint32_t i; + for(i=0;i<constant->m_Count;++i) + { + switch(constant->m_ValueArray[i].m_Type) + { + case kPositionType: valueArrayMask->m_PositionCount++; break; + case kQuaternionType: valueArrayMask->m_QuaternionCount++; break; + case kScaleType: valueArrayMask->m_ScaleCount++; break; + case kFloatType: valueArrayMask->m_FloatCount++; break; + case kInt32Type: valueArrayMask->m_IntCount++; break; + default: assert(false); break; + } + } + + valueArrayMask->m_IntValues = alloc.ConstructArray<bool>(valueArrayMask->m_IntCount); + valueArrayMask->m_FloatValues = alloc.ConstructArray<bool>(valueArrayMask->m_FloatCount); + valueArrayMask->m_PositionValues = alloc.ConstructArray<bool>(valueArrayMask->m_PositionCount); + valueArrayMask->m_QuaternionValues = alloc.ConstructArray<bool>(valueArrayMask->m_QuaternionCount); + valueArrayMask->m_ScaleValues = alloc.ConstructArray<bool>(valueArrayMask->m_ScaleCount); + + SetValueMask (valueArrayMask, false); + + return valueArrayMask; + } + + void DestroyValueArrayMask(ValueArrayMask *valueArrayMask, memory::Allocator& alloc) + { + if(valueArrayMask) + { + alloc.Deallocate(valueArrayMask->m_IntValues); + alloc.Deallocate(valueArrayMask->m_FloatValues); + alloc.Deallocate(valueArrayMask->m_PositionValues); + alloc.Deallocate(valueArrayMask->m_QuaternionValues); + alloc.Deallocate(valueArrayMask->m_ScaleValues); + alloc.Deallocate(valueArrayMask); + } + } + + ValueArray* CreateValueArray(ValueArrayConstant const* apValueArrayConstant, memory::Allocator& alloc) + { + SETPROFILERLABEL(ValueArray); + ValueArray* valueArray = alloc.Construct<ValueArray>(); + + uint32_t i; + for(i=0;i<apValueArrayConstant->m_Count;++i) + { + switch(apValueArrayConstant->m_ValueArray[i].m_Type) + { + case kPositionType: valueArray->m_PositionCount++; break; + case kQuaternionType: valueArray->m_QuaternionCount++; break; + case kScaleType: valueArray->m_ScaleCount++; break; + case kFloatType: valueArray->m_FloatCount++; break; + case kInt32Type: valueArray->m_IntCount++; break; + case kTriggerType: + case kBoolType: valueArray->m_BoolCount++; break; + default: assert(false); break; + } + } + + valueArray->m_BoolValues = alloc.ConstructArray<bool>(valueArray->m_BoolCount); + valueArray->m_IntValues = alloc.ConstructArray<int32_t>(valueArray->m_IntCount); + valueArray->m_FloatValues = alloc.ConstructArray<float>(valueArray->m_FloatCount); + valueArray->m_PositionValues = alloc.ConstructArray<math::float4>(valueArray->m_PositionCount); + valueArray->m_QuaternionValues = alloc.ConstructArray<math::float4>(valueArray->m_QuaternionCount); + valueArray->m_ScaleValues = alloc.ConstructArray<math::float4>(valueArray->m_ScaleCount); + + for(i=0;i<valueArray->m_BoolCount;++i) + valueArray->m_BoolValues[i] = false; + + for(i=0;i<valueArray->m_IntCount;++i) + valueArray->m_IntValues[i] = 0; + + for(i=0;i<valueArray->m_FloatCount;++i) + valueArray->m_FloatValues[i] = 0.f; + + for(i=0;i<valueArray->m_PositionCount;++i) + valueArray->m_PositionValues[i] = math::float4::zero(); + + for(i=0;i<valueArray->m_QuaternionCount;++i) + valueArray->m_QuaternionValues[i] = math::quatIdentity(); + + for(i=0;i<valueArray->m_ScaleCount;++i) + valueArray->m_ScaleValues[i] = math::float4::one(); + + return valueArray; + } + + void DestroyValueArray(ValueArray * apInput, memory::Allocator& alloc) + { + if(apInput) + { + alloc.Deallocate(apInput->m_BoolValues); + alloc.Deallocate(apInput->m_IntValues); + alloc.Deallocate(apInput->m_FloatValues); + alloc.Deallocate(apInput->m_PositionValues); + alloc.Deallocate(apInput->m_QuaternionValues); + alloc.Deallocate(apInput->m_ScaleValues); + + alloc.Deallocate(apInput); + } + } + + void ValueArrayCopy(ValueArray const* apSourceValueArray, ValueArray * apDestinationValueArray) + { + ValueArrayCopy(apSourceValueArray->m_BoolValues.Get(), apDestinationValueArray->m_BoolValues.Get(), apSourceValueArray->m_BoolCount, apDestinationValueArray->m_BoolCount); + ValueArrayCopy(apSourceValueArray->m_IntValues.Get(), apDestinationValueArray->m_IntValues.Get(), apSourceValueArray->m_IntCount, apDestinationValueArray->m_IntCount); + ValueArrayCopy(apSourceValueArray->m_FloatValues.Get(), apDestinationValueArray->m_FloatValues.Get(), apSourceValueArray->m_FloatCount, apDestinationValueArray->m_FloatCount); + ValueArrayCopy(apSourceValueArray->m_PositionValues.Get(), apDestinationValueArray->m_PositionValues.Get(), apSourceValueArray->m_PositionCount, apDestinationValueArray->m_PositionCount); + ValueArrayCopy(apSourceValueArray->m_QuaternionValues.Get(), apDestinationValueArray->m_QuaternionValues.Get(), apSourceValueArray->m_QuaternionCount, apDestinationValueArray->m_QuaternionCount); + ValueArrayCopy(apSourceValueArray->m_ScaleValues.Get(), apDestinationValueArray->m_ScaleValues.Get(), apSourceValueArray->m_ScaleCount, apDestinationValueArray->m_ScaleCount); + } + + void ValueArrayCopy(ValueArrayConstant const* sourceConstant, ValueArray const* source, ValueArrayConstant const* destinationConstant, ValueArray* destination, int32_t const* destinationInSourceIndexArray) + { + int dstCount = destinationConstant->m_Count; + + for(int dstIter = 0; dstIter < dstCount; dstIter++) + { + int32_t srcIndex = destinationInSourceIndexArray[dstIter]; + int32_t dstIndex = dstIter; + + if(srcIndex != -1 && sourceConstant->m_ValueArray[srcIndex].m_Type == destinationConstant->m_ValueArray[dstIndex].m_Type) + { + switch(sourceConstant->m_ValueArray[srcIndex].m_Type) + { + case kPositionType: + { + math::float4 value = source->ReadPosition(sourceConstant->m_ValueArray[srcIndex].m_Index); + destination->WritePosition(value, destinationConstant->m_ValueArray[dstIndex].m_Index); + break; + } + case kQuaternionType: + { + math::float4 value = source->ReadQuaternion(sourceConstant->m_ValueArray[srcIndex].m_Index); + destination->WriteQuaternion(value, destinationConstant->m_ValueArray[dstIndex].m_Index); + break; + } + case kScaleType: + { + math::float4 value = source->ReadScale(sourceConstant->m_ValueArray[srcIndex].m_Index); + destination->WriteScale(value, destinationConstant->m_ValueArray[dstIndex].m_Index); + break; + } + case kFloatType: + { + float value; + source->ReadData(value, sourceConstant->m_ValueArray[srcIndex].m_Index); + destination->WriteData(value, destinationConstant->m_ValueArray[dstIndex].m_Index); + break; + } + case kInt32Type: + { + int32_t value; + source->ReadData(value, sourceConstant->m_ValueArray[srcIndex].m_Index); + destination->WriteData(value, destinationConstant->m_ValueArray[dstIndex].m_Index); + break; + } + case kTriggerType: + case kBoolType: + { + bool value; + source->ReadData(value, sourceConstant->m_ValueArray[srcIndex].m_Index); + destination->WriteData(value, destinationConstant->m_ValueArray[dstIndex].m_Index); + break; + } + } + } + } + } + + void ValueArrayReverseCopy(ValueArrayConstant const* sourceConstant, ValueArray const* source, ValueArrayConstant const* destinationConstant, ValueArray* destination, int32_t const* sourceInDestinationIndexArray) + { + int srcCount = sourceConstant->m_Count; + + for(int srcIter = 0; srcIter < srcCount; srcIter++) + { + int32_t dstIndex = sourceInDestinationIndexArray[srcIter]; + int32_t srcIndex = srcIter; + + if(dstIndex != -1 && sourceConstant->m_ValueArray[srcIndex].m_Type == destinationConstant->m_ValueArray[dstIndex].m_Type) + { + switch(sourceConstant->m_ValueArray[srcIndex].m_Type) + { + case kPositionType: + { + math::float4 value = source->ReadPosition(sourceConstant->m_ValueArray[srcIndex].m_Index); + destination->WritePosition(value, destinationConstant->m_ValueArray[dstIndex].m_Index); + break; + } + case kQuaternionType: + { + math::float4 value = source->ReadQuaternion(sourceConstant->m_ValueArray[srcIndex].m_Index); + destination->WriteQuaternion(value, destinationConstant->m_ValueArray[dstIndex].m_Index); + break; + } + case kScaleType: + { + math::float4 value = source->ReadScale(sourceConstant->m_ValueArray[srcIndex].m_Index); + destination->WriteScale(value, destinationConstant->m_ValueArray[dstIndex].m_Index); + break; + } + case kFloatType: + { + float value; + source->ReadData(value, sourceConstant->m_ValueArray[srcIndex].m_Index); + destination->WriteData(value, destinationConstant->m_ValueArray[dstIndex].m_Index); + break; + } + case kInt32Type: + { + int32_t value; + source->ReadData(value, sourceConstant->m_ValueArray[srcIndex].m_Index); + destination->WriteData(value, destinationConstant->m_ValueArray[dstIndex].m_Index); + break; + } + case kTriggerType: + case kBoolType: + { + bool value; + source->ReadData(value, sourceConstant->m_ValueArray[srcIndex].m_Index); + destination->WriteData(value, destinationConstant->m_ValueArray[dstIndex].m_Index); + break; + } + } + } + } + } + + void ValueArrayCopy(ValueArray const *aSource, ValueArray* aValues, ValueArrayMask const *mask) + { + ValueArrayCopyMask (aSource->m_PositionValues.Get(), aValues->m_PositionValues.Get(), mask->m_PositionValues.Get(), aValues->m_PositionCount); + ValueArrayCopyMask (aSource->m_QuaternionValues.Get(), aValues->m_QuaternionValues.Get(), mask->m_QuaternionValues.Get(), aValues->m_QuaternionCount); + ValueArrayCopyMask (aSource->m_ScaleValues.Get(), aValues->m_ScaleValues.Get(), mask->m_ScaleValues.Get(), aValues->m_ScaleCount); + ValueArrayCopyMask (aSource->m_FloatValues.Get(), aValues->m_FloatValues.Get(), mask->m_FloatValues.Get(), aValues->m_FloatCount); + ValueArrayCopyMask (aSource->m_IntValues.Get(), aValues->m_IntValues.Get(), mask->m_IntValues.Get(), aValues->m_IntCount); + ValueArrayCopyMask (aSource->m_BoolValues.Get(), aValues->m_BoolValues.Get(), mask->m_BoolValues.Get(), aValues->m_BoolCount); + } + + static uint32_t GetLargestBlendIndex(const float *apWeightArray, uint32_t aCount) + { + float largest = apWeightArray[0]; + uint32_t index = 0; + for (int i=1;i<aCount;i++) + { + if (apWeightArray[i] > largest) + { + index = i; + largest = apWeightArray[i]; + } + } + + return index; + } + + + void ValueArrayBlend(ValueArray const *apValuesDefault,ValueArray* aValues, ValueArray ** aValuesArray, const float *apWeightArray, uint32_t aCount, ValueArrayMask const *mask) + { + // Blend positions + for (int valueIndex=0;valueIndex<aValues->m_PositionCount;valueIndex++) + { + if(!mask->m_PositionValues[valueIndex]) + continue; + + float sumW = 0; + math::float4 value4 = math::float4::zero(); + + for(int blendIter = 0; blendIter < aCount; blendIter++) + { + sumW += apWeightArray[blendIter]; + math::float1 w = math::float1(apWeightArray[blendIter]); + + math::float4 valuei = aValuesArray[blendIter]->ReadPosition(valueIndex); + value4 += valuei*w; + } + + if(sumW < 1.0f) + { + math::float1 wd = math::float1(1.0-sumW); + math::float4 valued = apValuesDefault->ReadPosition(valueIndex); + value4 += valued*math::float1(wd); + } + + aValues->WritePosition(value4,valueIndex); + } + + // Blend Quaternions + for (int valueIndex=0;valueIndex<aValues->m_QuaternionCount;valueIndex++) + { + if(!mask->m_QuaternionValues[valueIndex]) + continue; + + float sumW = 0; + math::float4 value4 = math::float4::zero(); + + for(int blendIter = 0; blendIter < aCount; blendIter++) + { + sumW += apWeightArray[blendIter]; + math::float1 w = math::float1(apWeightArray[blendIter]); + + math::float4 valuei = aValuesArray[blendIter]->ReadQuaternion(valueIndex); + value4 += math::cond(math::dot(value4,valuei) < math::float1::zero(), valuei * -w, valuei * w); + } + + if(sumW < 1.0f) + { + math::float1 wd = math::float1(1.0-sumW); + math::float4 valued = apValuesDefault->ReadQuaternion(valueIndex); + value4 += math::cond(math::dot(value4,valued) < math::float1::zero(), valued * -wd, valued * wd); + } + + value4 = math::normalize(value4); + aValues->WriteQuaternion(value4,valueIndex); + } + + // Blend scale + for (int valueIndex=0;valueIndex<aValues->m_ScaleCount;valueIndex++) + { + if(!mask->m_ScaleValues[valueIndex]) + continue; + + float sumW = 0; + math::float4 value4 = math::float4::one(); + + for(int blendIter = 0; blendIter < aCount; blendIter++) + { + sumW += apWeightArray[blendIter]; + math::float1 w = math::float1(apWeightArray[blendIter]); + + math::float4 valuei = aValuesArray[blendIter]->ReadScale(valueIndex); + math::float4 sng = math::sgn(valuei); + value4 = sng * math::abs( value4 * scaleWeight(valuei, w)); + } + + if(sumW < 1.0f) + { + math::float1 wd = math::float1(1.0-sumW); + + math::float4 valued = apValuesDefault->ReadScale(valueIndex); + math::float4 sng = math::sgn(valued); + value4 = sng * math::abs( value4 * scaleWeight(valued, wd)); + } + + aValues->WriteScale(value4,valueIndex); + } + + // Blend floats + for (int valueIndex=0;valueIndex<aValues->m_FloatCount;valueIndex++) + { + if(!mask->m_FloatValues[valueIndex]) + continue; + + float sumW = 0; + float value = 0; + + for(int blendIter = 0; blendIter < aCount; blendIter++) + { + float w = apWeightArray[blendIter]; + sumW += w; + + float valuei; + aValuesArray[blendIter]->ReadData(valuei,valueIndex); + value += valuei*w; + } + + if(sumW < 1.0f) + { + float wd = 1.0-sumW; + + float valued; + apValuesDefault->ReadData(valued,valueIndex); + value += valued*wd; + } + + aValues->WriteData(value,valueIndex); + } + + // Blend integers (pick by largest weight) + uint32_t largestBlendIndex = GetLargestBlendIndex (apWeightArray, aCount); + for (int valueIndex=0;valueIndex<aValues->m_IntCount;valueIndex++) + { + if(!mask->m_IntValues[valueIndex]) + continue; + + int32_t valueInt; + aValuesArray[largestBlendIndex]->ReadData(valueInt,valueIndex); + aValues->WriteData(valueInt,valueIndex); + } + } + + void ValueArrayAdd(ValueArray const *apValuesDefault, ValueArray const* apValues, ValueArrayMask const *readMask, float aWeight, bool aAdditive, ValueArray* apValuesOut, ValueArrayMask *defaultMask) + { + math::float1 w(aWeight); + float base1; + float value1; + math::float4 base4; + math::float4 value4; + int32_t valueInt; + + // Positions + for (int valueIndex=0;valueIndex<apValues->m_PositionCount;valueIndex++) + { + if(!readMask->m_PositionValues[valueIndex]) + continue; + + value4 = apValues->ReadPosition(valueIndex); + if(aAdditive) + { + if(defaultMask->m_PositionValues[valueIndex]) + base4 = apValuesDefault->ReadPosition(valueIndex); + else + base4 = apValuesOut->ReadPosition(valueIndex); + value4 = base4 + value4 * w; + } + else + { + if(aWeight < 1) + { + if(defaultMask->m_PositionValues[valueIndex]) + base4 = apValuesDefault->ReadPosition(valueIndex); + else + base4 = apValuesOut->ReadPosition(valueIndex); + + value4 = math::lerp(base4,value4,w); + } + } + apValuesOut->WritePosition(value4,valueIndex); + defaultMask->m_PositionValues[valueIndex] = false; + } + + // Quaternions + for (int valueIndex=0;valueIndex<apValues->m_QuaternionCount;valueIndex++) + { + if(!readMask->m_QuaternionValues[valueIndex]) + continue; + + value4 = apValues->ReadQuaternion(valueIndex); + if(aAdditive) + { + if(defaultMask->m_QuaternionValues[valueIndex]) + base4 = apValuesDefault->ReadQuaternion(valueIndex); + else + base4 = apValuesOut->ReadQuaternion(valueIndex); + + value4 = math::quatMul(base4,math::quatWeight(value4,w)); + } + else + { + if(aWeight < 1) + { + if(defaultMask->m_QuaternionValues[valueIndex]) + base4 = apValuesDefault->ReadQuaternion(valueIndex); + else + base4 = apValuesOut->ReadQuaternion(valueIndex); + + value4 = math::quatLerp(base4,value4,w); + } + } + apValuesOut->WriteQuaternion(value4,valueIndex); + defaultMask->m_QuaternionValues[valueIndex] = false; + } + + // Scale + for (int valueIndex=0;valueIndex<apValues->m_ScaleCount;valueIndex++) + { + if(!readMask->m_ScaleValues[valueIndex]) + continue; + + value4 = apValues->ReadScale(valueIndex); + if(aAdditive) + { + if(defaultMask->m_ScaleValues[valueIndex]) + base4 = apValuesDefault->ReadScale(valueIndex); + else + base4 = apValuesOut->ReadScale(valueIndex); + + value4 = base4 * math::scaleWeight(value4,w); + } + else + { + if(aWeight < 1) + { + if(defaultMask->m_ScaleValues[valueIndex]) + base4 = apValuesDefault->ReadScale(valueIndex); + else + base4 = apValuesOut->ReadScale(valueIndex); + + value4 = math::scaleBlend(base4,value4,w); + } + } + apValuesOut->WriteScale(value4,valueIndex); + defaultMask->m_ScaleValues[valueIndex] = false; + } + + // Floats + for (int valueIndex=0;valueIndex<apValues->m_FloatCount;valueIndex++) + { + if(!readMask->m_FloatValues[valueIndex]) + continue; + + apValues->ReadData(value1,valueIndex); + if(aAdditive) + { + if(defaultMask->m_FloatValues[valueIndex]) + apValuesDefault->ReadData(base1,valueIndex); + else + apValuesOut->ReadData(base1,valueIndex); + + value1 = base1 + value1 * aWeight; + } + else + { + if(aWeight < 1) + { + if(defaultMask->m_FloatValues[valueIndex]) + apValuesDefault->ReadData(base1,valueIndex); + else + apValuesOut->ReadData(base1,valueIndex); + + value1 = (1-aWeight) * base1 + value1 * aWeight; + } + } + apValuesOut->WriteData(value1,valueIndex); + defaultMask->m_FloatValues[valueIndex] = false; + } + + // Ints + if (aWeight > 0.5F) + { + for (int valueIndex=0;valueIndex<apValues->m_IntCount;valueIndex++) + { + if(!readMask->m_IntValues[valueIndex]) + continue; + + apValues->ReadData(valueInt,valueIndex); + apValuesOut->WriteData(valueInt,valueIndex); + defaultMask->m_IntValues[valueIndex] = false; + } + } + else + { + for (int valueIndex=0;valueIndex<apValues->m_IntCount;valueIndex++) + { + if(!readMask->m_IntValues[valueIndex]) + continue; + + if(defaultMask->m_IntValues[valueIndex]) + apValuesDefault->ReadData(valueInt,valueIndex); + else + apValuesOut->ReadData(valueInt,valueIndex); + + apValuesOut->WriteData(valueInt,valueIndex); + defaultMask->m_IntValues[valueIndex] = false; + } + } + } + + void ValueArraySub(ValueArray const &starts, ValueArray &values, ValueArrayMask const *mask) + { + float value,start; + math::float4 value4,start4; + + // Positions + for (int valueIndex=0;valueIndex<values.m_PositionCount;valueIndex++) + { + if(!mask->m_PositionValues[valueIndex]) + continue; + + value4 = values.ReadPosition(valueIndex); + start4 = starts.ReadPosition(valueIndex); + + value4 -= start4; + + values.WritePosition(value4,valueIndex); + } + + // Quaternions + for (int valueIndex=0;valueIndex<values.m_QuaternionCount;valueIndex++) + { + if(!mask->m_QuaternionValues[valueIndex]) + continue; + + value4 = values.ReadQuaternion(valueIndex); + start4 = starts.ReadQuaternion(valueIndex); + + value4 = math::normalize(math::quatMul(math::quatConj(start4),value4)); + + values.WriteQuaternion(value4,valueIndex); + } + + // Scale + for (int valueIndex=0;valueIndex<values.m_ScaleCount;valueIndex++) + { + if(!mask->m_ScaleValues[valueIndex]) + continue; + + value4 = values.ReadScale(valueIndex); + start4 = starts.ReadScale(valueIndex); + + value4 /= start4; + + values.WriteScale(value4,valueIndex); + } + + // Floats + for (int valueIndex=0;valueIndex<values.m_FloatCount;valueIndex++) + { + if(!mask->m_FloatValues[valueIndex]) + continue; + + values.ReadData(value,valueIndex); + starts.ReadData(start,valueIndex); + + value -= start; + + values.WriteData(value,valueIndex); + } + + // Integer substraction does not make sense + } + + void ValueArrayLoop( ValueArray const &starts, + ValueArray const &stops, + ValueArray &values, + float loopWeight, + const ValueArrayMask& mask) + { + math::float1 loopWeight1(loopWeight); + + float value,start,stop; + math::float4 value4,start4,stop4; + + // Positions + for (int valueIndex=0;valueIndex<values.m_PositionCount;valueIndex++) + { + if(!mask.m_PositionValues[valueIndex]) + continue; + + value4 = values.ReadPosition(valueIndex); + start4 = starts.ReadPosition(valueIndex); + stop4 = stops.ReadPosition(valueIndex); + + value4 += (start4 - stop4) * loopWeight1; + + values.WritePosition(value4,valueIndex); + } + + // Quaternions + for (int valueIndex=0;valueIndex<values.m_QuaternionCount;valueIndex++) + { + if(!mask.m_QuaternionValues[valueIndex]) + continue; + + value4 = values.ReadQuaternion(valueIndex); + start4 = starts.ReadQuaternion(valueIndex); + stop4 = stops.ReadQuaternion(valueIndex); + + value4 = math::normalize(math::quatMul(value4,math::quatWeight(math::quatMul(math::quatConj(stop4),start4),loopWeight1))); + + values.WriteQuaternion(value4,valueIndex); + } + + // Scales + for (int valueIndex=0;valueIndex<values.m_ScaleCount;valueIndex++) + { + if(!mask.m_ScaleValues[valueIndex]) + continue; + + value4 = values.ReadScale(valueIndex); + start4 = starts.ReadScale(valueIndex); + stop4 = stops.ReadScale(valueIndex); + + value4 *= math::scaleWeight(start4/stop4,loopWeight1); + + values.WriteScale(value4,valueIndex); + } + + // Floats + for (int valueIndex=0;valueIndex<values.m_FloatCount;valueIndex++) + { + if(!mask.m_FloatValues[valueIndex]) + continue; + + values.ReadData(value,valueIndex); + starts.ReadData(start,valueIndex); + stops.ReadData(stop,valueIndex); + + value += (start - stop) * loopWeight; + + values.WriteData(value,valueIndex); + } + } + + int32_t FindValueIndex(const ValueArrayConstant *aValueArrayConstant, uint32_t id) + { + int32_t ret = -1; + if(aValueArrayConstant) + { + uint32_t i; + for( i = 0 ; i < aValueArrayConstant->m_Count ; i++) + { + if(aValueArrayConstant->m_ValueArray[i].m_ID == id) + { + return i; + } + } + } + return ret; + } +} |