public void Bake(apPortrait portrait, apOptModifierUnitBase parentModifier, apModifierParamSetGroup srcParamSetGroup) { _portrait = portrait; _parentModifier = parentModifier; _syncTarget = srcParamSetGroup._syncTarget; //_keyControlParamName = srcParamSetGroup._keyControlParamName; _keyControlParamID = srcParamSetGroup._keyControlParamID; _keyControlParam = null; //<<이건 링크로 해결하자 //애니메이션 값도 넣어주자 _keyAnimClipID = srcParamSetGroup._keyAnimClipID; _keyAnimTimelineID = srcParamSetGroup._keyAnimTimelineID; _keyAnimTimelineLayerID = srcParamSetGroup._keyAnimTimelineLayerID; _keyAnimClip = null; _keyAnimTimeline = null; _keyAnimTimelineLayer = null; _paramSetList.Clear(); for (int i = 0; i < srcParamSetGroup._paramSetList.Count; i++) { apModifierParamSet srcParamSet = srcParamSetGroup._paramSetList[i]; apOptParamSet optParamSet = new apOptParamSet(); optParamSet.LinkParamSetGroup(this, portrait); optParamSet.BakeModifierParamSet(srcParamSet, portrait); _paramSetList.Add(optParamSet); } _isEnabled = srcParamSetGroup._isEnabled; _layerIndex = srcParamSetGroup._layerIndex; _layerWeight = srcParamSetGroup._layerWeight; _blendMethod = srcParamSetGroup._blendMethod; _isColorPropertyEnabled = srcParamSetGroup._isColorPropertyEnabled; //<<추가. _calculatedWeightedVertexList.Clear(); for (int i = 0; i < srcParamSetGroup._calculatedWeightedVertexList.Count; i++) { apModifierParamSetGroupVertWeight srcWV = srcParamSetGroup._calculatedWeightedVertexList[i]; apOptParamSetGroupVertWeight optWV = new apOptParamSetGroupVertWeight(); optWV.Bake(srcWV); optWV.Link(portrait.GetOptTransform(optWV._meshTransform_ID)); //OptTransform을 연결한다. _calculatedWeightedVertexList.Add(optWV); } LinkPortrait(portrait, parentModifier); }
// Init //-------------------------------------------- public apOptCalculatedResultParam(apCalculatedResultParam.CALCULATED_VALUE_TYPE calculatedValueType, apCalculatedResultParam.CALCULATED_SPACE calculatedSpace, apOptModifierUnitBase linkedModifier, apOptTransform targetOptTranform, apOptMesh targetOptMesh, apOptBone targetBone, //<<추가 apOptParamSetGroupVertWeight weightedVertData) { _calculatedValueType = calculatedValueType; _calculatedSpace = calculatedSpace; //TODO 여기서부터 작업하자 _linkedModifier = linkedModifier; _targetOptTransform = targetOptTranform; _targetOptMesh = targetOptMesh; _targetBone = targetBone; //<<추가 _weightedVertexData = weightedVertData; //Vertex 데이터가 들어간 경우 Vert 리스트를 만들어주자 if ((int)(_calculatedValueType & apCalculatedResultParam.CALCULATED_VALUE_TYPE.VertexPos) != 0) { int nPos = 0; if (_targetOptMesh.LocalVertPositions != null) { nPos = _targetOptMesh.LocalVertPositions.Length; } _result_Positions = new List <Vector2>(); _tmp_Positions = new List <Vector2>(); for (int i = 0; i < nPos; i++) { _result_Positions.Add(Vector2.zero); _tmp_Positions.Add(Vector2.zero); } } }
public void LinkWeightedVertexData(apOptParamSetGroupVertWeight weightedVertData) { _weightedVertexData = weightedVertData; }
// Init //-------------------------------------------- public apOptCalculatedResultParam(apCalculatedResultParam.CALCULATED_VALUE_TYPE calculatedValueType, apCalculatedResultParam.CALCULATED_SPACE calculatedSpace, apOptModifierUnitBase linkedModifier, apOptTransform targetOptTranform, apOptTransform ownerOptTranform, apOptMesh targetOptMesh, apOptBone targetBone, //<<추가 apOptParamSetGroupVertWeight weightedVertData) { _calculatedValueType = calculatedValueType; _calculatedSpace = calculatedSpace; //TODO 여기서부터 작업하자 _linkedModifier = linkedModifier; _targetOptTransform = targetOptTranform; _ownerOptTransform = ownerOptTranform; _targetOptMesh = targetOptMesh; _targetBone = targetBone; //<<추가 _paramKeyValues.Clear(); _subParamKeyValueList.Clear(); _weightedVertexData = weightedVertData; _isVertexLocalMorph = false; _isVertexRigging = false; //Vertex 데이터가 들어간 경우 Vert 리스트를 만들어주자 if ((int)(_calculatedValueType & apCalculatedResultParam.CALCULATED_VALUE_TYPE.VertexPos) != 0) { int nPos = 0; if (_targetOptMesh.LocalVertPositions != null) { nPos = _targetOptMesh.LocalVertPositions.Length; } _result_Positions = new Vector2[nPos]; _tmp_Positions = new Vector2[nPos]; for (int i = 0; i < nPos; i++) { _result_Positions[i] = Vector2.zero; _tmp_Positions[i] = Vector2.zero; } if (_linkedModifier._modifierType == apModifierBase.MODIFIER_TYPE.Rigging) { _result_VertMatrices = new apMatrix3x3[nPos]; _tmp_VertMatrices = new apMatrix3x3[nPos]; for (int i = 0; i < nPos; i++) { _result_VertMatrices[i].SetIdentity(); _tmp_VertMatrices[i].SetIdentity(); } } //if(_linkedModifier._modifierType == apModifierBase.MODIFIER_TYPE.Morph || // _linkedModifier._modifierType == apModifierBase.MODIFIER_TYPE.AnimatedMorph) //{ // //최적화를 위한 VertLocalPair를 만든다. 개수는 ParamSetGroup 만큼 // _result_VertLocalPairs = new apOptVertexRequest[_linkedModifier._paramSetGroupList.Count]; // for (int iVLP = 0; iVLP < _result_VertLocalPairs.Length; iVLP++) // { // apOptVertexRequest newRequest = new apOptVertexRequest(); // newRequest.InitVertLocalPair(_linkedModifier._paramSetGroupList[iVLP]); // _result_VertLocalPairs[iVLP] = newRequest; // } //} if (_linkedModifier._modifierType == apModifierBase.MODIFIER_TYPE.AnimatedMorph || _linkedModifier._modifierType == apModifierBase.MODIFIER_TYPE.Morph) { _isVertexLocalMorph = true; } else if (_linkedModifier._modifierType == apModifierBase.MODIFIER_TYPE.Rigging) { _isVertexRigging = true; } } }
//Link가 모두 끝난 후 실행시켜준다. //Modifier -> Target Tranform (=RenderUnit)을 CalculatedParam을 이용해 연결해준다. public void LinkModifierStackToRenderUnitCalculateStack(bool isRoot, apOptTransform rootOptTransform, bool isRecursive) { //RenderUnit => OptTransform //전체 Modifier중에서 RenderUnit을 포함한 Modifer를 찾는다. //그 중, RenderUnit에 대한것만 처리할 CalculateResultParam을 만들고 연동한다. //ResultParam을 RenderUnit의 CalculateStack에 넣는다. //if (_parentTransform != null) //{ // Debug.Log(">> [Opt] LinkModifierStackToRenderUnitCalculateStack - " + _parentTransform._name + "(Root : " + rootOptTransform._name + ")"); //} //else if(isRoot) //{ // Debug.Log(">> [Opt] LinkModifierStackToRenderUnitCalculateStack - " + rootOptTransform._name + " - Root"); //} //여기서 버그가 발생되었다. if (_nModifiers != _modifiers.Count) { _nModifiers = _modifiers.Count; } for (int iMod = 0; iMod < _nModifiers; iMod++) { //Modifier ->.. apOptModifierUnitBase modifier = _modifiers[iMod]; List <apOptParamSetGroup> paramSetGroups = modifier._paramSetGroupList; for (int iGroup = 0; iGroup < paramSetGroups.Count; iGroup++) { //Modifier -> ParamSetGroup ->.. apOptParamSetGroup paramSetGroup = paramSetGroups[iGroup]; List <apOptParamSet> paramSets = paramSetGroup._paramSetList; for (int iParam = 0; iParam < paramSets.Count; iParam++) { //Modifier -> ParamSetGroup -> ParamSet ->... apOptParamSet paramSet = paramSets[iParam]; List <apOptModifiedMesh> modMeshes = paramSet._meshData; List <apOptModifiedBone> modBones = paramSet._boneData; for (int iModMesh = 0; iModMesh < modMeshes.Count; iModMesh++) { //[핵심] //Modifier -> ParamSetGroup -> ParamSet -> ModMeh //이제 이 ModMesh와 타겟 Transform을 연결하자. //연결할땐 Calculated 오브젝트를 만들어서 연결 apOptModifiedMesh modMesh = modMeshes[iModMesh]; if (modMesh._targetTransform != null) { //이미 만든 Calculate Param이 있는지 확인 apOptCalculatedResultParam existParam = modifier.GetCalculatedResultParam(modMesh._targetTransform); apOptParamSetGroupVertWeight weightedVertexData = null; if (modMesh._targetMesh != null) { weightedVertexData = paramSetGroup.GetWeightVertexData(modMesh._targetTransform); } if (existParam != null) { //이미 존재하는 Calculated Param이 있다. existParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, modMesh, null); //추가 12.5 //이미 추가된 ResultParam에 ParamKeyValue가 추가될 때 CalculateStack이 갱신되는 경우가 있다. modMesh._targetTransform.CalculatedStack.OnParamKeyValueAddedOnCalculatedResultParam(existParam); } else { //새로 Calculated Param을 만들어야 한다. apOptCalculatedResultParam newCalParam = new apOptCalculatedResultParam( modifier._calculatedValueType, modifier._calculatedSpace, modifier, modMesh._targetTransform, modMesh._targetTransform, modMesh._targetMesh, null, weightedVertexData); newCalParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, modMesh, null); //Modifier에 등록하고 modifier._calculatedResultParams.Add(newCalParam); //OptTranform에도 등록하자 modMesh._targetTransform.CalculatedStack.AddCalculatedResultParam(newCalParam); } } } //변경 10.2 : //기존 : ModBone의 _meshGroup_Bone에 해당하는 OptTransform에 연결했다. //변경 : ModBone은 항상 RootBone에 연결한다. for (int iModBone = 0; iModBone < modBones.Count; iModBone++) { apOptModifiedBone modBone = modBones[iModBone]; if (modBone._bone == null || modBone._meshGroup_Bone == null) { Debug.LogError("ModBone -> Calculate Link (Opt) 실패"); continue; } //<BONE_EDIT> //apOptCalculatedResultParam existParam = modifier.GetCalculatedResultParam_Bone( // modBone._meshGroup_Bone, modBone._bone); //변경 apOptCalculatedResultParam existParam = modifier.GetCalculatedResultParam_Bone( rootOptTransform, modBone._bone, modBone._meshGroup_Bone); if (existParam != null) { //이미 있다면 ModBone만 추가해주자 existParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, null, modBone); //Debug.LogWarning(" < Exist > - Mod Bone [" + modBone._bone._name + " << " + modBone._meshGroup_Bone._name + "]"); } else { //Debug.Log("Mod Bone -> Calculate Param 등록"); //새로 CalculateParam을 만들고 //<BONE_EDIT> //apOptCalculatedResultParam newCalParam = new apOptCalculatedResultParam( // modifier._calculatedValueType, // modifier._calculatedSpace, // modifier, // modBone._meshGroup_Bone, // modBone._meshGroup_Bone._childMesh, // modBone._bone, // null//WeightedVertex // ); //Debug.LogError(" < New > - Mod Bone [" + modBone._bone._name + " << " + modBone._meshGroup_Bone._name + "]"); apOptCalculatedResultParam newCalParam = new apOptCalculatedResultParam( modifier._calculatedValueType, modifier._calculatedSpace, modifier, rootOptTransform, //<<변경 modBone._meshGroup_Bone, //추가 modBone._meshGroup_Bone._childMesh, modBone._bone, null //WeightedVertex ); newCalParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, null, modBone); // Modifier에 등록하고 modifier._calculatedResultParams.Add(newCalParam); //RenderUnit에도 등록을 하자 //<BONE_EDIT> //modBone._meshGroup_Bone.CalculatedStack.AddCalculatedResultParam(newCalParam); //변경 rootOptTransform.CalculatedStack.AddCalculatedResultParam(newCalParam); } } } } //Modifier에서 //SubList를 한번 정렬하자 for (int iCal = 0; iCal < modifier._calculatedResultParams.Count; iCal++) { modifier._calculatedResultParams[iCal].SortSubList(); } } //추가>> //하위 객체에 대해서도 Link를 자동으로 수행한다. //다 끝나고 Sort apOptTransform childTransform = null; if (_parentTransform != null) { if (isRecursive) { if (_parentTransform._childTransforms != null && _parentTransform._childTransforms.Length > 0) { for (int i = 0; i < _parentTransform._childTransforms.Length; i++) { childTransform = _parentTransform._childTransforms[i]; if (childTransform._unitType == apOptTransform.UNIT_TYPE.Group) { if (childTransform != _parentTransform) { //<<여기서도 같이 수행 childTransform._modifierStack.LinkModifierStackToRenderUnitCalculateStack(false, rootOptTransform, true); } } } } } if (isRoot) { //Root인 경우 //RenderUnit들을 검사하면서 Calculated Stack에 대해서 Sort를 해주자 SortAllCalculatedStack(_parentTransform); } } else { Debug.LogError("<<<< Error : Mod Link시 Parent Transform이 연결이 안되었다"); } }
//Link가 모두 끝난 후 실행시켜준다. //Modifier -> Target Tranform (=RenderUnit)을 CalculatedParam을 이용해 연결해준다. public void LinkModifierStackToRenderUnitCalculateStack(bool isRoot = true) { //RenderUnit => OptTransform //전체 Modifier중에서 RenderUnit을 포함한 Modifer를 찾는다. //그 중, RenderUnit에 대한것만 처리할 CalculateResultParam을 만들고 연동한다. //ResultParam을 RenderUnit의 CalculateStack에 넣는다. for (int iMod = 0; iMod < _nModifiers; iMod++) { //Modifier ->.. apOptModifierUnitBase modifier = _modifiers[iMod]; List <apOptParamSetGroup> paramSetGroups = modifier._paramSetGroupList; for (int iGroup = 0; iGroup < paramSetGroups.Count; iGroup++) { //Modifier -> ParamSetGroup ->.. apOptParamSetGroup paramSetGroup = paramSetGroups[iGroup]; List <apOptParamSet> paramSets = paramSetGroup._paramSetList; for (int iParam = 0; iParam < paramSets.Count; iParam++) { //Modifier -> ParamSetGroup -> ParamSet ->... apOptParamSet paramSet = paramSets[iParam]; List <apOptModifiedMesh> modMeshes = paramSet._meshData; List <apOptModifiedBone> modBones = paramSet._boneData; for (int iModMesh = 0; iModMesh < modMeshes.Count; iModMesh++) { //[핵심] //Modifier -> ParamSetGroup -> ParamSet -> ModMeh //이제 이 ModMesh와 타겟 Transform을 연결하자. //연결할땐 Calculated 오브젝트를 만들어서 연결 apOptModifiedMesh modMesh = modMeshes[iModMesh]; if (modMesh._targetTransform != null) { //이미 만든 Calculate Param이 있는지 확인 apOptCalculatedResultParam existParam = modifier.GetCalculatedResultParam(modMesh._targetTransform); apOptParamSetGroupVertWeight weightedVertexData = null; if (modMesh._targetMesh != null) { weightedVertexData = paramSetGroup.GetWeightVertexData(modMesh._targetTransform); } if (existParam != null) { //이미 존재하는 Calculated Param이 있다. existParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, modMesh, null); } else { //새로 Calculated Param을 만들어야 한다. apOptCalculatedResultParam newCalParam = new apOptCalculatedResultParam( modifier._calculatedValueType, modifier._calculatedSpace, modifier, modMesh._targetTransform, modMesh._targetMesh, null, weightedVertexData); newCalParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, modMesh, null); //Modifier에 등록하고 modifier._calculatedResultParams.Add(newCalParam); //OptTranform에도 등록하자 modMesh._targetTransform.CalculatedStack.AddCalculatedResultParam(newCalParam); } } } for (int iModBone = 0; iModBone < modBones.Count; iModBone++) { apOptModifiedBone modBone = modBones[iModBone]; if (modBone._bone == null || modBone._meshGroup_Bone == null) { Debug.LogError("ModBone -> Calculate Link (Opt) 실패"); continue; } apOptCalculatedResultParam existParam = modifier.GetCalculatedResultParam_Bone( modBone._meshGroup_Bone, modBone._bone); if (existParam != null) { //이미 있다면 ModBone만 추가해주자 existParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, null, modBone); } else { //Debug.Log("Mod Bone -> Calculate Param 등록"); //새로 CalculateParam을 만들고 apOptCalculatedResultParam newCalParam = new apOptCalculatedResultParam( modifier._calculatedValueType, modifier._calculatedSpace, modifier, modBone._meshGroup_Bone, modBone._meshGroup_Bone._childMesh, modBone._bone, null //WeightedVertex ); newCalParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, null, modBone); // Modifier에 등록하고 modifier._calculatedResultParams.Add(newCalParam); //RenderUnit에도 등록을 하자 modBone._meshGroup_Bone.CalculatedStack.AddCalculatedResultParam(newCalParam); } } } } //Modifier에서 //SubList를 한번 정렬하자 for (int iCal = 0; iCal < modifier._calculatedResultParams.Count; iCal++) { modifier._calculatedResultParams[iCal].SortSubList(); } } //추가>> //하위 객체에 대해서도 Link를 자동으로 수행한다. //다 끝나고 Sort apOptTransform childTransform = null; if (_parentTransform != null) { if (_parentTransform._childTransforms != null && _parentTransform._childTransforms.Length > 0) { for (int i = 0; i < _parentTransform._childTransforms.Length; i++) { childTransform = _parentTransform._childTransforms[i]; if (childTransform._unitType == apOptTransform.UNIT_TYPE.Group) { if (childTransform != _parentTransform) { childTransform._modifierStack.LinkModifierStackToRenderUnitCalculateStack(false); //<<여기서도 같이 수행 } } } } if (isRoot) { //Root인 경우 //RenderUnit들을 검사하면서 Calculated Stack에 대해서 Sort를 해주자 SortAllCalculatedStack(_parentTransform); } } }