/// <summary> /// ModMesh와 연동되는 ParamKeyValue 생성 /// </summary> public OptParamKeyValueSet(apOptParamSetGroup keyParamSetGroup, apOptParamSet paramSet, apOptModifiedMesh modifiedMesh) { _keyParamSetGroup = keyParamSetGroup; _paramSet = paramSet; _modifiedMesh = modifiedMesh; _layerIndex = _keyParamSetGroup._layerIndex; _modifiedBone = null; }
/// <summary> /// ModBone과 연동되는 ParamKeyValue 생성 /// </summary> public OptParamKeyValueSet(apOptParamSetGroup keyParamSetGroup, apOptParamSet paramSet, apOptModifiedBone modifiedBone) { _keyParamSetGroup = keyParamSetGroup; _paramSet = paramSet; _modifiedMesh = null; _layerIndex = _keyParamSetGroup._layerIndex; _modifiedBone = modifiedBone; //추가 : RotationBias _isAnimRotationBias = false; _animRotationBiasAngle = 0; _animRotationBiasAngle_Prev = -1; _animRotationBiasedMatrix = new apMatrix(); }
/// <summary> /// ParamSet을 받아서 SubList와 연동한다. /// </summary> /// <param name="paramSet"></param> /// <returns></returns> public void AddParamSetAndModifiedValue(apOptParamSetGroup paramSetGroup, apOptParamSet paramSet, apOptModifiedMesh modifiedMesh, apOptModifiedBone modifiedBone) { OptParamKeyValueSet existSet = GetParamKeyValue(paramSet); if (existSet != null) { //이미 존재한 값이라면 패스 return; } //새로운 KeyValueSet을 만들어서 리스트에 추가하자 //Mod Mesh 또는 Mod Bone 둘중 하나를 넣어서 ParamKeyValueSet을 구성하자 OptParamKeyValueSet newKeyValueSet = null; if (modifiedMesh != null) { newKeyValueSet = new OptParamKeyValueSet(paramSetGroup, paramSet, modifiedMesh); } else if (modifiedBone != null) { newKeyValueSet = new OptParamKeyValueSet(paramSetGroup, paramSet, modifiedBone); } else { Debug.LogError("AddParamSetAndModifiedMesh Error : ModifiedMesh와 ModifiedBone이 모두 Null이다."); return; } _paramKeyValues.Add(newKeyValueSet); apOptCalculatedResultParamSubList targetSubList = null; apOptCalculatedResultParamSubList existSubList = _subParamKeyValueList.Find(delegate(apOptCalculatedResultParamSubList a) { return(a._keyParamSetGroup == paramSetGroup); }); //같이 묶여서 작업할 SubList가 있는가 if (existSubList != null) { targetSubList = existSubList; } else { //없으면 만든다. targetSubList = new apOptCalculatedResultParamSubList(this, _isVertexLocalMorph, _isVertexRigging); targetSubList.SetParamSetGroup(paramSetGroup); _subParamKeyValueList.Add(targetSubList); if (_isVertexLocalMorph || _isVertexRigging) { //VertexRequest를 전체 리스트로 추가하여 관리하자 if (_result_VertLocalPairs == null) { _result_VertLocalPairs = new List <apOptVertexRequest>(); } _result_VertLocalPairs.Add(targetSubList._vertexRequest); } } //해당 SubList에 위에서 만든 KeyValueSet을 추가하자 if (targetSubList != null) { targetSubList.AddParamKeyValueSet(newKeyValueSet); } _isAnimModifier = (paramSetGroup._syncTarget == apModifierParamSetGroup.SYNC_TARGET.KeyFrame); }
public void BakeModifierParamSet(apModifierParamSet srcParamSet, apPortrait portrait) { //switch (srcParamSet._syncTarget) //{ // case apModifierParamSet.SYNC_TARGET.Static: // _syncTarget = SYNC_TARGET.Static; // break; // case apModifierParamSet.SYNC_TARGET.Controller: // _syncTarget = SYNC_TARGET.Controller; // break; // case apModifierParamSet.SYNC_TARGET.KeyFrame: // _syncTarget = SYNC_TARGET.KeyFrame; // break; // default: // Debug.LogError("연동 에러 : ParamSet에 정의되지 않은 타입 : " + srcParamSet._syncTarget); // break; //} //_controlKeyName = srcParamSet._controlKeyName; //_conSyncValue_Bool = srcParamSet._conSyncValue_Bool; _conSyncValue_Int = srcParamSet._conSyncValue_Int; _conSyncValue_Float = srcParamSet._conSyncValue_Float; _conSyncValue_Vector2 = srcParamSet._conSyncValue_Vector2; //_conSyncValue_Vector3 = srcParamSet._conSyncValue_Vector3; //_conSyncValue_Color = srcParamSet._conSyncValue_Color; _keyframeUniqueID = srcParamSet._keyframeUniqueID; _syncKeyframe = null; _overlapWeight = srcParamSet._overlapWeight; //OverlapWeight를 집어넣자 _meshData.Clear(); _boneData.Clear(); //SrcModifier ParamSet의 ModMesh, ModBone을 Bake해주자 //Debug.LogError("TODO : Bone 데이터 연동"); for (int i = 0; i < srcParamSet._meshData.Count; i++) { apModifiedMesh srcModMesh = srcParamSet._meshData[i]; apOptModifiedMesh optModMesh = new apOptModifiedMesh(); bool isResult = optModMesh.Bake(srcModMesh, portrait); if (isResult) { _meshData.Add(optModMesh); } } //추가 : ModBone for (int i = 0; i < srcParamSet._boneData.Count; i++) { apModifiedBone srcModBone = srcParamSet._boneData[i]; apOptModifiedBone optModBone = new apOptModifiedBone(); bool isResult = optModBone.Bake(srcModBone, portrait); if (isResult) { _boneData.Add(optModBone); } } }
//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]; bool isUseModMeshSet = modifier._isUseModMeshSet; //19.5.24 추가 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; //추가 19.5.24 < ModMesh대신 ModMeshSet을 사용하자 List <apOptModifiedMeshSet> modMeshSets = paramSet._meshSetData; //변경 19.5.24 //기존의 ModMesh가 불필요하게 데이터를 모두 가지고 있어서 용량이 많았다. //개선된 ModMeshSet으로 변경하여 최적화 if (isUseModMeshSet) { //개선된 ModMeshSet을 사용하는 경우 apOptModifiedMeshSet modMeshSet = null; for (int iModMeshSet = 0; iModMeshSet < modMeshSets.Count; iModMeshSet++) { modMeshSet = modMeshSets[iModMeshSet]; if (modMeshSet._targetTransform != null) { //이미 만든 Calculate Param이 있는지 확인 apOptCalculatedResultParam existParam = modifier.GetCalculatedResultParam(modMeshSet._targetTransform); if (existParam != null) { //이미 존재하는 Calculated Param이 있다. existParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, null, null, modMeshSet); //추가 12.5 //이미 추가된 ResultParam에 ParamKeyValue가 추가될 때 CalculateStack이 갱신되는 경우가 있다. modMeshSet._targetTransform.CalculatedStack.OnParamKeyValueAddedOnCalculatedResultParam(existParam); } else { //새로 Calculated Param을 만들어야 한다. apOptCalculatedResultParam newCalParam = new apOptCalculatedResultParam( modifier._calculatedValueType, modifier._calculatedSpace, modifier, modMeshSet._targetTransform, modMeshSet._targetTransform, modMeshSet._targetMesh, null //weightedVertexData//<<사용 안함 19.5.20 ); newCalParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, null, null, modMeshSet); //Modifier에 등록하고 modifier._calculatedResultParams.Add(newCalParam); //OptTranform에도 등록하자 modMeshSet._targetTransform.CalculatedStack.AddCalculatedResultParam(newCalParam); } } } } else { //기존의 ModMesh를 사용하는 경우 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); // 삭제 19.5.20 : apOptParamSetGroupVertWeight는 더이상 사용하지 않음 //apOptParamSetGroupVertWeight weightedVertexData = null; //if (modMesh._targetMesh != null) //{ // weightedVertexData = paramSetGroup.GetWeightVertexData(modMesh._targetTransform); //} if (existParam != null) { //이미 존재하는 Calculated Param이 있다. existParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, modMesh, null, 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//<<사용 안함 19.5.20 ); newCalParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, modMesh, null, 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, null); //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 > 19.5.20 : 삭제 ); newCalParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, null, modBone, null); // 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); } } }
public void BakeModifierParamSet(apModifierParamSet srcParamSet, apPortrait portrait, bool isUseModMeshSet) { _conSyncValue_Int = srcParamSet._conSyncValue_Int; _conSyncValue_Float = srcParamSet._conSyncValue_Float; _conSyncValue_Vector2 = srcParamSet._conSyncValue_Vector2; _keyframeUniqueID = srcParamSet._keyframeUniqueID; _syncKeyframe = null; _overlapWeight = srcParamSet._overlapWeight; //OverlapWeight를 집어넣자 _meshData.Clear(); _boneData.Clear(); //19.5.23 : meshSetData 추가 if (_meshSetData == null) { _meshSetData = new List <apOptModifiedMeshSet>(); } _meshSetData.Clear(); _isUseModMeshSet = isUseModMeshSet; //<<이 값이 1.1.7부터는 true가 된다. if (!_isUseModMeshSet) { //이전버전 //SrcModifier ParamSet의 ModMesh, ModBone을 Bake해주자 for (int i = 0; i < srcParamSet._meshData.Count; i++) { apModifiedMesh srcModMesh = srcParamSet._meshData[i]; apOptModifiedMesh optModMesh = new apOptModifiedMesh(); bool isResult = optModMesh.Bake(srcModMesh, portrait); if (isResult) { _meshData.Add(optModMesh); } } } else { //변경된 버전 : 19.5.23 (v.1.1.7) for (int i = 0; i < srcParamSet._meshData.Count; i++) { apModifiedMesh srcModMesh = srcParamSet._meshData[i]; apOptModifiedMeshSet optModMeshSet = new apOptModifiedMeshSet(); bool isResult = optModMeshSet.Bake( srcParamSet._parentParamSetGroup._parentModifier, srcParamSet._parentParamSetGroup, srcModMesh, portrait); if (isResult) { _meshSetData.Add(optModMeshSet); } } } //ModBone for (int i = 0; i < srcParamSet._boneData.Count; i++) { apModifiedBone srcModBone = srcParamSet._boneData[i]; apOptModifiedBone optModBone = new apOptModifiedBone(); bool isResult = optModBone.Bake(srcModBone, portrait); if (isResult) { _boneData.Add(optModBone); } } }