public void LinkLog_Transform(apCalculatedLog modified, apCalculatedLog toParent, apCalculatedLog parentWorld, apCalculatedLog worldTransform) { _linkedTF_Modified = modified; _linkedTF_ToParent = toParent; _linkedTF_ParentWorld = parentWorld; _linkedTF_WorldTransform = worldTransform; }
/// <summary> /// CalResultStackLayer 하위에서 계산된 CalResultParam의 Log를 연결하는 함수 /// CalResultParam -> CalResultStackLayer으로 연결할때의 함수 /// </summary> /// <param name="calResultParam"></param> public void LinkLog_ResultParam(apCalculatedLog calResultParam) { if (!_childCalParamResultLogs.Contains(calResultParam)) { _childCalParamResultLogs.Add(calResultParam); } calResultParam._parentCalResultStackLayer = this; }
// Link private void LinkLog_ModLayerParent(apCalculatedLog parentLayer) { _parentLayerLog = parentLayer; if (!parentLayer._childLayerLogs.Contains(this)) { parentLayer._childLayerLogs.Add(this); } }
/// <summary> /// 변형된 modMatrix에 대해서 StackLayer, CalParamResult, ParamSet 상에서 레이어 보간된 연산을 역으로 수행하여 /// 요청된 Target Modified Matrix 레벨에서 어떤 값을 가져야 하는지 리턴한다. /// [Matrix에 대한 역 보간처리 함수] /// </summary> /// <param name="targetModifiedLog"></param> /// <param name="layer_ParamSetGroupLog"></param> /// <param name="layer_CalParamResultLog"></param> /// <param name="stackLayer_MeshTransformLog"></param> /// <param name="modMatrix_next"></param> /// <returns></returns> private apMatrix GetInverseInterpolatedMatrix(apCalculatedLog layer_ParamSetGroupLog, apCalculatedLog layer_CalParamResultLog, apCalculatedLog stackLayer_MeshTransformLog, apMatrix modMatrix_next ) { //1. StackLayer -> CalParamResultLog if (!stackLayer_MeshTransformLog._childCalParamResultLogs.Contains(layer_CalParamResultLog)) { return(null); } //Debug.Log("GetInvMatrix"); //for (int i = 0; i < stackLayer_MeshTransformLog._childCalParamResultLogs.Count; i++) //{ // Debug.Log("Cal Param [" + i + "] : " + stackLayer_MeshTransformLog._childCalParamResultLogs[i]._calResultParam._linkedModifier.DisplayName + " / " // + stackLayer_MeshTransformLog._childCalParamResultLogs[i]._layerBlendType + " (" + stackLayer_MeshTransformLog._childCalParamResultLogs[i]._weight + ")"); //} //for (int i = 0; i < layer_CalParamResultLog._childLayerLogs.Count; i++) //{ // Debug.Log("ParamSetGroup [" + i + "] : " + layer_CalParamResultLog._childLayerLogs[i]._paramSetGroup._keyControlParam._keyName + " / " // + layer_CalParamResultLog._childLayerLogs[i]._layerBlendType + " ( " + layer_CalParamResultLog._childLayerLogs[i]._weight + ")" // + "\r\n" + layer_CalParamResultLog._childLayerLogs[i]._paramSetGroup._tmpMatrix); //} //1. StackLayer -> CalParamResultLog apMatrix modMatrix_CalParamResultLog = GetSubInverseLayeredMatrix(layer_CalParamResultLog, stackLayer_MeshTransformLog, modMatrix_next); if (modMatrix_CalParamResultLog == null) { Debug.LogError("GetInverseInterpolatedMatrix 실패 : StackLayer -> CalParamResultLog를 처리할 수 없다."); return(null); } //Debug.Log("Calculate : 1. StackLayer -> CalParamResultLog\r\n" + modMatrix_next + "\r\n >>>> \r\n" + modMatrix_CalParamResultLog); //2. CalParamResultLog -> ParamSetGroupLog (ParamSet은 하나만 선택했으니 ParamSet 레벨과 동일하다) apMatrix modMatrix_ParamSetGroupLog = GetSubInverseLayeredMatrix(layer_ParamSetGroupLog, layer_CalParamResultLog, modMatrix_CalParamResultLog); if (modMatrix_ParamSetGroupLog == null) { Debug.LogError("GetInverseInterpolatedMatrix 실패 : StackLayer -> CalParamResultLog를 처리할 수 없다."); return(null); } //Debug.Log("Calculate : 2. CalParamResultLog -> ParamSetGroupLog\r\n" + modMatrix_CalParamResultLog + "\r\n >>>> \r\n" + modMatrix_ParamSetGroupLog); return(modMatrix_ParamSetGroupLog); }
public void LinkLog_CalResultStackLayer(apCalculatedLog layer0_rigging, apCalculatedLog layer1_StaticMesh, apCalculatedLog layer2_VertLocal, apCalculatedLog layer3_MeshTransform, apCalculatedLog layer4_VertWorld ) { _linkedStackLayer_0_Rigging = layer0_rigging; _linkedStackLayer_1_StaticMesh = layer1_StaticMesh; _linkedStackLayer_2_VertLocal = layer2_VertLocal; _linkedStackLayer_3_MeshTransform = layer3_MeshTransform; _linkedStackLayer_4_VertWorld = layer4_VertWorld; }
// Functions //----------------------------------------------- /// <summary> /// 기록을 초기화 한다. /// </summary> public void ReadyToRecord() { _parentLayerLog = null; _childLayerLogs.Clear(); _childCalParamResultLogs.Clear(); _childCalStackLayer_TF = null; _parentCalResultStackLayer = null; _parentTF_Modified = null; _childCalStackLayer_TF = null; _paramSetGroupLayerIndex = -1; _calResultParamLayerIndex = -1; }
//3) Layer_CalParamResult public void Calculate_CalParamResult(float layerWeight, int iLayer, apModifierBase.BLEND_METHOD blendMethod, apCalculatedLog resultStackLayerLog ) { _weight = layerWeight; _calResultParamLayerIndex = iLayer; //_calResultParamBlendType = blendMethod; switch (blendMethod) { case apModifierBase.BLEND_METHOD.Additive: _layerBlendType = BLEND_METHOD.Additive; break; case apModifierBase.BLEND_METHOD.Interpolation: _layerBlendType = BLEND_METHOD.Interpolation; break; } resultStackLayerLog.LinkLog_ResultParam(this); }
//2) Layer_ParamSetGroup public void CalculateParamSetGroup(float layerWeight, int iLayer, apModifierParamSetGroup.BLEND_METHOD blendType, apModifierParamSetGroupVertWeight paramSetGroupVertWeight, apCalculatedLog calPraramResultLog ) { _weight = layerWeight; _paramSetGroupLayerIndex = iLayer; switch (blendType) { case apModifierParamSetGroup.BLEND_METHOD.Additive: _layerBlendType = BLEND_METHOD.Additive; break; case apModifierParamSetGroup.BLEND_METHOD.Interpolation: _layerBlendType = BLEND_METHOD.Interpolation; break; } //_paramSetGroupBlendType = blendType; _paramSetGroupVertWeight = paramSetGroupVertWeight; //<<보통은 Null LinkLog_ModLayerParent(calPraramResultLog); }
public void SetModifiedTransform(apMatrix matrix_modified, apCalculatedLog calResultStack_CalLog) { _matrix_TF_LocalModified.SetMatrix(matrix_modified); CalculatedLog.LinkLog_CalculateResultStackTF(calResultStack_CalLog); }
public apMatrix GetSubInverseLayeredMatrix(apCalculatedLog targetLog, apCalculatedLog parentLog, apMatrix parentMatrix) { apMatrix invUpperLayerMatrix = new apMatrix(parentMatrix); apMatrix lowerLayerMatrix = new apMatrix(); //타겟보다 낮은 레이어는 따로 합을 구한다. LOG_TYPE layerLogType = targetLog._logType; int nLayers = 0; int iLayer = -1; if (layerLogType == LOG_TYPE.Layer_CalParamResult) { nLayers = parentLog._childCalParamResultLogs.Count; iLayer = parentLog._childCalParamResultLogs.IndexOf(targetLog); } else if (layerLogType == LOG_TYPE.Layer_ParamSetGroup) { nLayers = parentLog._childLayerLogs.Count; iLayer = parentLog._childLayerLogs.IndexOf(targetLog); } else { Debug.LogError("Layer가 없는 LogType [" + layerLogType + "] 이다"); return(null); } if (iLayer < 0) { Debug.LogError("존재하지 않는 Log [" + layerLogType + "]"); return(null); } lowerLayerMatrix.SetIdentity(); //Debug.LogWarning(">> Lower To Layer [0 > " + iLayer + "]"); //낮은 레이어에서는 값을 더하자 if (iLayer > 0) { for (int i = 0; i < iLayer; i++) { apCalculatedLog calLog = null; apMatrix calMatrix = null; switch (layerLogType) { case LOG_TYPE.Layer_CalParamResult: calLog = parentLog._childCalParamResultLogs[i]; calMatrix = calLog._calResultParam._result_Matrix; break; case LOG_TYPE.Layer_ParamSetGroup: calLog = parentLog._childLayerLogs[i]; calMatrix = calLog._paramSetGroup._tmpMatrix; break; } float weight = calLog._weight; if (!calLog._isWeight) { weight = 1.0f; } //string prevMatrix = lowerLayerMatrix.ToString(); if (i == 0) { lowerLayerMatrix.SetPos(calMatrix._pos * weight); lowerLayerMatrix.SetRotate(calMatrix._angleDeg * weight); lowerLayerMatrix.SetScale(calMatrix._scale * weight + Vector2.one * (1.0f - weight)); lowerLayerMatrix.MakeMatrix(); } else { switch (calLog._layerBlendType) { case BLEND_METHOD.Interpolation: BlendMatrix_ITP(lowerLayerMatrix, calMatrix, weight); //Debug.Log("[" + i + "] ITP/" + weight + " : " + prevMatrix + " >> " + calMatrix + " => " + lowerLayerMatrix); break; case BLEND_METHOD.Additive: BlendMatrix_Add(lowerLayerMatrix, calMatrix, weight); //Debug.Log("[" + i + "] ADD/" + weight + " : " + prevMatrix + " >> " + calMatrix + " => " + lowerLayerMatrix); break; } } } } //Debug.LogWarning(">> Upper To Layer [" + (nLayers - 1) + " > " + iLayer + "]"); //위 레이어에서는 값을 빼자 if (iLayer < nLayers - 1) { for (int i = (nLayers - 1); i >= iLayer + 1; i--) { apCalculatedLog calLog = null; apMatrix calMatrix = null; switch (layerLogType) { case LOG_TYPE.Layer_CalParamResult: calLog = parentLog._childCalParamResultLogs[i]; calMatrix = calLog._calResultParam._result_Matrix; break; case LOG_TYPE.Layer_ParamSetGroup: calLog = parentLog._childLayerLogs[i]; calMatrix = calLog._paramSetGroup._tmpMatrix; break; } float weight = calLog._weight; if (!calLog._isWeight) { weight = 1.0f; } switch (calLog._layerBlendType) { case BLEND_METHOD.Interpolation: InverseBlendMatrix_ITP(invUpperLayerMatrix, calMatrix, weight); break; case BLEND_METHOD.Additive: InverseBlendMatrix_Add(invUpperLayerMatrix, calMatrix, weight); break; } } } apMatrix result = null; float weight_calParam = targetLog._weight; if (!targetLog._isWeight) { weight_calParam = 1.0f; } apMatrix calTargetMatrix = null; switch (layerLogType) { case LOG_TYPE.Layer_CalParamResult: calTargetMatrix = targetLog._calResultParam._result_Matrix; break; case LOG_TYPE.Layer_ParamSetGroup: calTargetMatrix = targetLog._paramSetGroup._tmpMatrix; break; } switch (targetLog._layerBlendType) { case BLEND_METHOD.Additive: result = InverseBlendMatrixTarget_Add(invUpperLayerMatrix, lowerLayerMatrix, calTargetMatrix, weight_calParam); break; case BLEND_METHOD.Interpolation: result = InverseBlendMatrixTarget_ITP(invUpperLayerMatrix, lowerLayerMatrix, calTargetMatrix, weight_calParam); break; } if (result == null) { return(null); } return(result); }
public InverseResult World2ModLocalPos_TransformRotationScaling(float deltaRotateAngle, Vector2 deltaScale) { if (_modMesh == null) { Debug.LogError("World2ModLocalPos_Transform 실패 : ModMesh에서 호출하지 않았다."); return(null); } if (_modMesh._transform_Mesh == null) { Debug.LogError("World2ModLocalPos_Transform 실패 : ModMesh의 MeshTransform이 Null이다."); return(null); } //현재 위치를 받자 //이제 위로 하나씩 계산하면서 어떤 CalculateLog가 기록되었는지 확인하자 //StatckLResultLayer까지 올라가면 된다. (거기는 값이 고정이므로) apCalculatedLog modified = this; apCalculatedLog layer_ParamSetGroup = modified._parentLayerLog; apCalculatedLog layer_CalParamResult = layer_ParamSetGroup._parentLayerLog; apCalculatedLog stackLayer_MeshTransform = layer_CalParamResult._parentCalResultStackLayer; apCalculatedLog transform_Modified = stackLayer_MeshTransform._parentTF_Modified; //현재 posW 를 저장하자 Vector2 posW_prev = _modMesh._transform_Mesh._matrix_TFResult_World._pos; //일단 회전값/스케일을 추가하자 apMatrix RSModMatrix = new apMatrix(_modMesh._transform_Mesh._matrix_TF_LocalModified); RSModMatrix.SetRotate(RSModMatrix._angleDeg + deltaRotateAngle); RSModMatrix.SetScale(RSModMatrix._scale + deltaScale); apMatrix RSWorldMatrix = new apMatrix(_modMesh._transform_Mesh._matrix_TF_ToParent); RSWorldMatrix.RMultiply(RSModMatrix); RSWorldMatrix.RMultiply(_modMesh._transform_Mesh._matrix_TF_ParentWorld); //이 WorldMatrix의 계산 후 Position을 확인하자 Vector2 posW_rs = RSWorldMatrix._pos; //posW_rotated가 아닌 posW_prev로 돌려야 한다. 고치자. Vector2 deltaPosW = posW_prev - posW_rs; _inverseResult.Request(posW_rs, deltaPosW); //이제 역으로 내려오자 // ParentWorld <- Modified <- ToParent = World // [Modified <- ToParent] = [ParentWorld-1 <- World] // Modified = [ParentWorld-1 <- World <- ToParent-1] apMatrix worldMatrix_next = new apMatrix(RSWorldMatrix); worldMatrix_next.SetPos(worldMatrix_next._pos + deltaPosW); apMatrix modMatrix_next = transform_Modified._meshTransform._matrix_TF_ToParent.RInverseMatrix; modMatrix_next.RMultiply(worldMatrix_next); modMatrix_next.RInverse(transform_Modified._meshTransform._matrix_TF_ParentWorld); //위 수식은 "StackLayer-MeshTF" 레벨에서 계산된 것이다. //StackLayer -> CalParam -> ParamSetGroup으로 이동하자. apMatrix modMatrix_paramSet = GetInverseInterpolatedMatrix(layer_ParamSetGroup, layer_CalParamResult, stackLayer_MeshTransform, modMatrix_next); if (modMatrix_paramSet == null) { Debug.LogError("StackLayer -> CalParam -> ParamSetGroup 전환에 실패했다."); return(null); } //_inverseResult.SetResult(transform_Modified._meshTransform._matrix_TF_LocalModified._pos, // modMatrix_next._pos); _inverseResult.SetResult(transform_Modified._meshTransform._matrix_TF_LocalModified._pos, modMatrix_paramSet._pos); return(_inverseResult); }
/// <summary> /// Modified 단계에서 위로 검색하여 현재 World Position으로부터 다시 Local로 내려온다. /// 결과값은 ModMesh(TF)의 TransformMatrix에 사용될 값으로 변환된다. /// ModMesh에서 호출해야한다. /// </summary> /// <param name="deltaPosW"></param> /// <returns></returns> //public InverseResult World2ModLocalPos_TransformMove(Vector2 nextPosW) public InverseResult World2ModLocalPos_TransformMove(Vector2 nextPosW, Vector2 deltaPosW) { if (_modMesh == null) { Debug.LogError("World2ModLocalPos_Transform 실패 : ModMesh에서 호출하지 않았다."); return(null); } if (_modMesh._transform_Mesh == null) { Debug.LogError("World2ModLocalPos_Transform 실패 : ModMesh의 MeshTransform이 Null이다."); return(null); } //현재 위치를 받자 Vector2 posW_prev = _modMesh._transform_Mesh._matrix_TFResult_World._pos; //Vector2 deltaPosW = nextPosW - posW_prev; nextPosW = posW_prev + deltaPosW; _inverseResult.Request(posW_prev, deltaPosW); //이제 위로 하나씩 계산하면서 어떤 CalculateLog가 기록되었는지 확인하자 //StatckLResultLayer까지 올라가면 된다. (거기는 값이 고정이므로) apCalculatedLog modified = this; apCalculatedLog layer_ParamSetGroup = modified._parentLayerLog; apCalculatedLog layer_CalParamResult = layer_ParamSetGroup._parentLayerLog; apCalculatedLog stackLayer_MeshTransform = layer_CalParamResult._parentCalResultStackLayer; apCalculatedLog transform_Modified = stackLayer_MeshTransform._parentTF_Modified; //Debug.Log("Calculate Log"); //이제 역으로 내려오자 Vector2 posW_next = nextPosW; apMatrix worldMatrix = transform_Modified._meshTransform._matrix_TFResult_World; // ParentWorld <- Modified <- ToParent = World // [Modified <- ToParent] = [ParentWorld-1 <- World] // Modified = [ParentWorld-1 <- World <- ToParent-1] apMatrix worldMatrix_next = new apMatrix(worldMatrix); worldMatrix_next.SetPos(worldMatrix_next._pos + deltaPosW); apMatrix modMatrix_next = transform_Modified._meshTransform._matrix_TF_ToParent.RInverseMatrix; modMatrix_next.RMultiply(worldMatrix_next); modMatrix_next.RInverse(transform_Modified._meshTransform._matrix_TF_ParentWorld); //위 수식은 "StackLayer-MeshTF" 레벨에서 계산된 것이다. //StackLayer -> CalParam -> ParamSetGroup으로 이동하자. apMatrix modMatrix_paramSet = GetInverseInterpolatedMatrix(layer_ParamSetGroup, layer_CalParamResult, stackLayer_MeshTransform, modMatrix_next); if (modMatrix_paramSet == null) { Debug.LogError("StackLayer -> CalParam -> ParamSetGroup 전환에 실패했다."); return(null); } //_inverseResult.SetResult(transform_Modified._meshTransform._matrix_TF_LocalModified._pos, // modMatrix_next._pos); _inverseResult.SetResult(transform_Modified._meshTransform._matrix_TF_LocalModified._pos, modMatrix_paramSet._pos); return(_inverseResult); }
// 계산 갱신 //Modified, // Layer_ParamSetGroup, // Layer_CalParamResult, // Transform_Modified, // Transform_ToParent, // Transform_ParentWorld, // Transform_WorldTransform,//<<위 3개(또는 1개)가 완성 // CalResultStackLayer_0_Rigging, // CalResultStackLayer_1_StaticMesh, // CalResultStackLayer_2_VertLocal, // CalResultStackLayer_3_MeshTransform, // CalResultStackLayer_4_VertWorld //1) Modified public void CalculateModified(float weight, apCalculatedLog paramSetGroupLog) { _weight = weight; LinkLog_ModLayerParent(paramSetGroupLog); }
/// <summary> /// MeshTransform_Modified에 CalStackResult-TF의 Lof를 연결하는 함수 /// CalResultStackLayer (TF) -> MeshTrasnform으로 연결할때의 함수 /// </summary> /// <param name="calResultStackTF"></param> public void LinkLog_CalculateResultStackTF(apCalculatedLog calResultStackTF) { _childCalStackLayer_TF = calResultStackTF; calResultStackTF._parentTF_Modified = this; }