// Init - Bake //-------------------------------------------- public bool Bake(apModifiedMesh srcModMesh, apPortrait portrait) { _portrait = portrait; _rootMeshGroupUniqueID = srcModMesh._meshGroupUniqueID_Modifier; _meshUniqueID = srcModMesh._meshUniqueID; _transformUniqueID = srcModMesh._transformUniqueID; //_boneUniqueID = srcModMesh._boneUniqueID; _isMeshTransform = srcModMesh._isMeshTransform; apOptTransform rootTransform = _portrait.GetOptTransformAsMeshGroup(_rootMeshGroupUniqueID); apOptTransform targetTransform = _portrait.GetOptTransform(_transformUniqueID); if (targetTransform == null) { Debug.LogError("Bake 실패 : 찾을 수 없는 연결된 OptTransform [" + _transformUniqueID + "]"); Debug.LogError("이미 삭제된 객체에 연결된 ModMesh가 아닌지 확인해보세염"); return(false); } apOptMesh targetMesh = null; if (targetTransform._unitType == apOptTransform.UNIT_TYPE.Mesh) { targetMesh = targetTransform._childMesh; } if (rootTransform == null) { Debug.LogError("ModifiedMesh 연동 에러 : 알수 없는 RootTransform"); return(false); } //_targetType = srcModMesh._targetType; _modValueType = srcModMesh._modValueType; //switch (srcModMesh._targetType) Color meshColor = srcModMesh._meshColor; if (!srcModMesh._isVisible) { meshColor.a = 0.0f; } _isUsePhysicParam = srcModMesh._isUsePhysicParam; if (_isUsePhysicParam) { _physicMeshParam = new apOptPhysicsMeshParam(); _physicMeshParam.Bake(srcModMesh.PhysicParam); _physicMeshParam.Link(_portrait); } //추가 ExtraOption _isExtraValueEnabled = srcModMesh._isExtraValueEnabled; _extraValue.Bake(srcModMesh._extraValue); if (!_extraValue._isDepthChanged && !_extraValue._isTextureChanged) { _isExtraValueEnabled = false; } //Modifier Value에 맞게 Bake를 하자 if ((int)(srcModMesh._modValueType & apModifiedMesh.MOD_VALUE_TYPE.VertexPosList) != 0) { Bake_VertexMorph(rootTransform, targetTransform, targetMesh, srcModMesh._vertices, meshColor, srcModMesh._isVisible); } else if ((int)(srcModMesh._modValueType & apModifiedMesh.MOD_VALUE_TYPE.TransformMatrix) != 0) { if (srcModMesh._isMeshTransform) { Bake_MeshTransform(rootTransform, targetTransform, targetMesh, srcModMesh._transformMatrix, meshColor, srcModMesh._isVisible); } else { Bake_MeshGroupTransform(rootTransform, targetTransform, srcModMesh._transformMatrix, meshColor, srcModMesh._isVisible); } } else if ((int)(srcModMesh._modValueType & apModifiedMesh.MOD_VALUE_TYPE.BoneVertexWeightList) != 0) { //추가 : VertRig 데이터를 넣는다. bool isValidVertexRigsData = Bake_VertexRigs(rootTransform, targetTransform, targetMesh, srcModMesh._vertRigs); if (!isValidVertexRigsData) { //유효하지 않은 Rigging의 ModMesh가 있다. //Rig 데이터가 아무것도 없는 ModMesh는 Opt에서 오작동을 한다. (오류 검사를 안하므로) //Debug.LogError("Rig 데이터가 없는 ModMesh"); string strTransform = rootTransform._name + " / " + targetTransform._name; Debug.LogError("AnyPortrait : Vertices with missing rigging data have been detected. Rigging for [" + strTransform + "] is not Bake."); return(false); } } else if ((int)(srcModMesh._modValueType & apModifiedMesh.MOD_VALUE_TYPE.VertexWeightList_Physics) != 0 || (int)(srcModMesh._modValueType & apModifiedMesh.MOD_VALUE_TYPE.VertexWeightList_Volume) != 0) { Bake_VertexWeights(rootTransform, targetTransform, targetMesh, srcModMesh._vertWeights); } else { Debug.LogError("연동 에러 : 알 수 없는 ModifierMesh 타입 : " + srcModMesh._modValueType); return(false); } return(true); }
// 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; //<<추가 _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; } } }
// Editor Functions //------------------------------------------------ public void Bake(apPortrait portrait, //apMeshGroup srcMeshGroup, apOptTransform parentTransform, apOptRootUnit rootUnit, string name, int transformID, int meshGroupUniqueID, apMatrix defaultMatrix, bool isMesh, int level, int depth, bool isVisible_Default, Color meshColor2X_Default, float zScale ) { _portrait = portrait; _rootUnit = rootUnit; _transformID = transformID; _name = name; _meshGroupUniqueID = meshGroupUniqueID; _parentTransform = parentTransform; _defaultMatrix = new apMatrix(defaultMatrix); _transform = transform; _level = level; _depth = depth; _isVisible_Default = isVisible_Default; _meshColor2X_Default = meshColor2X_Default; float depthZPos = 0.0f; if (parentTransform != null) { //_depth -= parentTransform._depth; depthZPos = (float)(_depth - parentTransform._depth) * zScale; } else { depthZPos = (float)_depth * zScale; } //이부분 실험 중 //1. Default Matrix를 Transform에 적용하고, Modifier 계산에서는 제외하는 경우 //결과 : Bake시에는 "Preview"를 위해서 DefaultMatrix 위치로 이동을 시키지만, 실행시에는 원점으로 이동시킨다. //_transform.localPosition = _defaultMatrix.Pos3 - new Vector3(0.0f, 0.0f, (float)_depth); //_transform.localRotation = Quaternion.Euler(0.0f, 0.0f, _defaultMatrix._angleDeg); //_transform.localScale = _defaultMatrix._scale; //2. Default Matrix를 Modifier에 포함시키고 Transform은 원점인 경우 (Editor와 동일) _transform.localPosition = -new Vector3(0.0f, 0.0f, depthZPos); _transform.localRotation = Quaternion.identity; _transform.localScale = Vector3.one; if (isMesh) { _unitType = UNIT_TYPE.Mesh; } else { _unitType = UNIT_TYPE.Group; } _childTransforms = null; _childMesh = null; }
public void LinkOpt(apAnimClip animClip, apAnimTimeline timeline) { _parentAnimClip = animClip; _parentTimeline = timeline; _linkType = _parentTimeline._linkType; if (_parentAnimClip == null) { Debug.Log("AnyPortrait Error : Parent Anim Clip is Null"); } else if (_parentAnimClip._targetOptTranform == null) { Debug.LogError("AnyPortrait Error : Parent Anim Clip TargetOptTranform is Null"); } switch (_linkType) { case apAnimClip.LINK_TYPE.AnimatedModifier: { switch (_linkModType) { case LINK_MOD_TYPE.MeshTransform: //수정 : 재귀적으로 링크를 수행한다. _linkedOptTransform = _parentAnimClip._targetOptTranform.GetMeshTransformRecursive(_transformID); if (_linkedOptTransform == null) { Debug.LogError("AnyPortrait Error : Opt TimelineLayer MeshTransform Linking Failed : " + _transformID); _transformID = -1; } break; case LINK_MOD_TYPE.MeshGroupTransform: //수정 : 재귀적으로 링크를 수행한다. _linkedOptTransform = _parentAnimClip._targetOptTranform.GetMeshGroupTransformRecursive(_transformID); if (_linkedOptTransform == null) { Debug.LogError("AnyPortrait Error : Opt TimelineLayer MeshGroupTransform Linking Failed : " + _transformID); _transformID = -1; } break; case LINK_MOD_TYPE.Bone: //TODO : Bone 타입 연결을 해야한다. _linkedOptBone = _parentAnimClip._targetOptTranform.GetBoneRecursive(_boneID); break; case LINK_MOD_TYPE.None: _linkedOptTransform = null; _transformID = -1; _boneID = -1; break; } } break; case apAnimClip.LINK_TYPE.ControlParam: { _linkedControlParam = _parentAnimClip._portrait.GetControlParam(_controlParamID); if (_linkedControlParam == null) { _controlParamID = -1; } } break; //case apAnimClip.LINK_TYPE.Bone: // { // Debug.LogError("TODO : TimelineLayer의 Bone 타입 연동하기"); // } // break; } for (int i = 0; i < _keyframes.Count; i++) { _keyframes[i].Link(this); } SortAndRefreshKeyframes(); }
public void Parse(GameObject targetGameObject, apBakeLinkParam parentLinkParam) { _prevGameObject = targetGameObject; _isRecycled = false; _isReGroupCompleted = false; //Parent-Child를 서로 연결하자 _parentLinkParam = parentLinkParam; if (parentLinkParam != null) { if (_parentLinkParam._childLinkParams == null) { _parentLinkParam._childLinkParams = new List <apBakeLinkParam>(); } _parentLinkParam._childLinkParams.Add(this); } //Component를 보고 이 객체의 성격을 정의하자 _isOptGameObject = false; _optRoot = null; _optNode = null; _optBone = null; _optTransform = null; _optMesh = null; _meshRenderer = null; _meshFilter = null; _isOtherComponentExist = false; MeshRenderer compMeshRenderer = null; MeshFilter compMeshFilter = null; Component[] components = _prevGameObject.GetComponents(typeof(Component)); if (components != null) { Component curComp = null; for (int i = 0; i < components.Length; i++) { curComp = components[i]; if (curComp is Transform) { //? 이건 필수로 들어가는 겁니더.. continue; } if (curComp is apOptRootUnit) { _optRoot = curComp as apOptRootUnit; } else if (curComp is apOptTransform) { _optTransform = curComp as apOptTransform; } else if (curComp is apOptNode) { _optNode = curComp as apOptNode; } else if (curComp is apOptBone) { _optBone = curComp as apOptBone; } else if (curComp is apOptMesh) { _optMesh = curComp as apOptMesh; } else if (curComp is MeshRenderer) { compMeshRenderer = curComp as MeshRenderer; } else if (curComp is MeshFilter) { compMeshFilter = curComp as MeshFilter; } else { //알 수 없는 컴포넌트가 있다. _isOtherComponentExist = true; } } } if (_optRoot != null || _optNode != null || _optBone != null || _optTransform != null || _optMesh != null) { // Opt 계열의 컴포넌트가 있다면 _isOptGameObject = true; } //만약 MeshRenderer/MeshFilter가 있을때 //_optMesh가 있다면 포함가능, //그 외에는 "알 수 없는 컴포넌트"로 지정한다. if (compMeshRenderer != null) { if (_optMesh != null) { _meshRenderer = compMeshRenderer; } else { _isOtherComponentExist = true; } } if (compMeshFilter != null) { if (_optMesh != null) { _meshFilter = compMeshFilter; } else { _isOtherComponentExist = true; } } }
// Bake //--------------------------------------------------------------------------------- public bool Bake(apModifierBase srcModifier, apModifierParamSetGroup srcModParamSetGroup, apModifiedMesh srcModMesh, apPortrait portrait) { _portrait = portrait; _rootMeshGroupUniqueID = srcModMesh._meshGroupUniqueID_Modifier; _meshUniqueID = srcModMesh._meshUniqueID; _transformUniqueID = srcModMesh._transformUniqueID; //_boneUniqueID = srcModMesh._boneUniqueID; _isMeshTransform = srcModMesh._isMeshTransform; apOptTransform rootTransform = _portrait.GetOptTransformAsMeshGroup(_rootMeshGroupUniqueID); apOptTransform targetTransform = _portrait.GetOptTransform(_transformUniqueID); if (targetTransform == null) { Debug.LogError("Bake 실패 : 찾을 수 없는 연결된 OptTransform [" + _transformUniqueID + "]"); Debug.LogError("이미 삭제된 객체에 연결된 ModMesh가 아닌지 확인해보세염"); return(false); } apOptMesh targetMesh = null; if (targetTransform._unitType == apOptTransform.UNIT_TYPE.Mesh) { targetMesh = targetTransform._childMesh; } if (rootTransform == null) { Debug.LogError("ModifiedMesh 연동 에러 : 알수 없는 RootTransform"); return(false); } _rootTransform = rootTransform; _targetTransform = targetTransform; _targetMesh = targetMesh; //각각의 타입 _dataType = DATA_TYPE.None; //1. Vertex if ((int)(srcModMesh._modValueType & apModifiedMesh.MOD_VALUE_TYPE.VertexPosList) != 0) { Bake_Vertex(srcModMesh._vertices); } //2. Transform if ((int)(srcModMesh._modValueType & apModifiedMesh.MOD_VALUE_TYPE.TransformMatrix) != 0) { Bake_Transform(srcModMesh._transformMatrix); } //3. Rigging if ((int)(srcModMesh._modValueType & apModifiedMesh.MOD_VALUE_TYPE.BoneVertexWeightList) != 0) { Bake_VertexRigs(srcModMesh._vertRigs); } //4. Physics if ((int)(srcModMesh._modValueType & apModifiedMesh.MOD_VALUE_TYPE.VertexWeightList_Physics) != 0 && srcModMesh._isUsePhysicParam) { Bake_Physics(srcModMesh.PhysicParam, srcModMesh._vertWeights, portrait); } if (((int)(srcModMesh._modValueType & apModifiedMesh.MOD_VALUE_TYPE.VertexPosList) != 0) || ((int)(srcModMesh._modValueType & apModifiedMesh.MOD_VALUE_TYPE.TransformMatrix) != 0) ) { //Morph, Transform 모디파이어에서.. //5. Color if (srcModifier._isColorPropertyEnabled && srcModParamSetGroup._isColorPropertyEnabled) { //색상 옵션이 켜진 경우 Color meshColor = srcModMesh._meshColor; if (!srcModMesh._isVisible) { meshColor.a = 0.0f; } Bake_Color(meshColor, srcModMesh._isVisible); } //6. Extra if (srcModMesh._isExtraValueEnabled && (srcModMesh._extraValue._isDepthChanged || srcModMesh._extraValue._isTextureChanged) ) { //Extra 옵션이 켜진 경우 Bake_ExtraValue(srcModMesh); } } return(true); }
public void Bake(apModifierStack modStack, apPortrait portrait) { _portrait = portrait; _modifiers.Clear(); _parentTransformID = -1; _parentTransform = null; if (modStack._parentMeshGroup != null) { //MeshGroup 타입의 OptTransform을 찾자 apOptTransform optTransform = _portrait.GetOptTransformAsMeshGroup(modStack._parentMeshGroup._uniqueID); if (optTransform != null) { _parentTransformID = optTransform._transformID; _parentTransform = optTransform; } } if (_parentTransform == null) { Debug.LogError("Opt Modifier Stack -> Null Opt Transform"); } //Modifier를 Bake해주자 for (int i = 0; i < modStack._modifiers.Count; i++) { apModifierBase modifier = modStack._modifiers[i]; apOptModifierUnitBase optMod = new apOptModifierUnitBase(); ////ModifierType에 맞게 상속된 클래스로 생성한다. //switch (modifier.ModifierType) //{ // case apModifierBase.MODIFIER_TYPE.Base: // optMod = new apOptModifierUnitBase(); // break; // case apModifierBase.MODIFIER_TYPE.AnimatedMorph: // break; // case apModifierBase.MODIFIER_TYPE.Morph: // optMod = new apOptModifierUnit_Morph();//Morph // break; // case apModifierBase.MODIFIER_TYPE.Physic: // break; // case apModifierBase.MODIFIER_TYPE.Rigging: // break; // case apModifierBase.MODIFIER_TYPE.Volume: // break; // default: // Debug.LogError("apOptModifierSubStack Bake : 알 수 없는 Mod 타입 : " + modifier.ModifierType); // break; //} if (optMod != null) { optMod.Bake(modifier, _portrait); optMod.Link(_portrait, _parentTransform); _modifiers.Add(optMod); } } _nModifiers = _modifiers.Count; }
public void AddChildTransform(apOptTransform optTransform, apSortedRenderBuffer.BufferData srcBufferData) //파라미터 추가 { _optTransforms.Add(optTransform); _sortedRenderBuffer.Bake_AddTransform(optTransform, srcBufferData); //<< 부분 추가 12.6 }
//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이 연결이 안되었다"); } }
public void Link(apOptTransform optTransform) { _optTransform = optTransform; }
//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 RigBoneWeightPair(apOptTransform optTransform, apOptBone bone, float weight) { _optTransform = optTransform; _bone = bone; _weight = weight; }
// Init //-------------------------------------------- public apOptCalculatedResultStack(apOptTransform parentOptTransform) { _parentOptTransform = parentOptTransform; _targetOptMesh = _parentOptTransform._childMesh; }