// Functions //--------------------------------------------------------- // Keyframe -> File public void SetAnimKeyframe(int unitID, apAnimKeyframe animKeyframe) { _unitID = unitID; _keyframeUniqueID = animKeyframe._uniqueID; _linkedKeyframe = animKeyframe; _frameIndex = animKeyframe._frameIndex; _isKeyValueSet = animKeyframe._isKeyValueSet; _isActive = animKeyframe._isActive; _isLoopAsStart = animKeyframe._isLoopAsStart; _isLoopAsEnd = animKeyframe._isLoopAsEnd; _loopFrameIndex = animKeyframe._loopFrameIndex; _activeFrameIndexMin = animKeyframe._activeFrameIndexMin; _activeFrameIndexMax = animKeyframe._activeFrameIndexMax; _activeFrameIndexMin_Dummy = animKeyframe._activeFrameIndexMin_Dummy; _activeFrameIndexMax_Dummy = animKeyframe._activeFrameIndexMax_Dummy; //Curve 정보 _curve_PrevTangentType = animKeyframe._curveKey._prevTangentType; _curve_PrevSmoothX = animKeyframe._curveKey._prevSmoothX; _curve_PrevSmoothY = animKeyframe._curveKey._prevSmoothY; _curve_NextTangentType = animKeyframe._curveKey._nextTangentType; _curve_NextSmoothX = animKeyframe._curveKey._nextSmoothX; _curve_NextSmoothY = animKeyframe._curveKey._nextSmoothY; //Control Param 타입이면 //Control Param의 어떤 값에 동기화되는가 _conSyncValue_Int = animKeyframe._conSyncValue_Int; _conSyncValue_Float = animKeyframe._conSyncValue_Float; _conSyncValue_Vector2 = animKeyframe._conSyncValue_Vector2; //Modifier Mesh 타입일때 _isModMeshType = animKeyframe._linkedModMesh_Editor != null; _isModBoneType = animKeyframe._linkedModBone_Editor != null; //>> Transform만 저장한다. _modTransformMatrix = new apMatrix(); _modMeshColor = Color.black; _modVisible = true; if (_isModMeshType) { _modTransformMatrix.SetMatrix(animKeyframe._linkedModMesh_Editor._transformMatrix); _modMeshColor = animKeyframe._linkedModMesh_Editor._meshColor; _modVisible = animKeyframe._linkedModMesh_Editor._isVisible; } else if (_isModBoneType) { _modTransformMatrix.SetMatrix(animKeyframe._linkedModBone_Editor._transformMatrix); } }
public apLinkedMatrix SetMatrixWrap(apMatrix matrixWrap, CALCULATE_TYPE calculateType, float lerpIfInterpolation = 1.0f) { _valueType = VALUE_TYPE.MatrixWrap; if (_matrixWrap == null) { _matrixWrap = new apMatrix(matrixWrap); } else { _matrixWrap.SetMatrix(matrixWrap); } _calculateType = calculateType; if (_calculateType == CALCULATE_TYPE.Interpolation) { _lerp = lerpIfInterpolation; } _weight = 1.0f; _isWeight = false; _weightCalAdded = 1.0f; _isWeightCalAdded = false; return(this); }
/// <summary> /// Parent의 Matrix를 추가한다. (Parent x This) /// </summary> /// <param name="matrix_parentTransform"></param> //public void AddWorldMatrix_Parent(apMatrix3x3 matrix_parentTransform) public void AddWorldMatrix_Parent(apMatrix matrix_parentTransform) { //_matrix_TF_Cal_Parent = matrix_parentTransform.MtrxToSpace * _matrix_TF_Cal_Parent; ////_calculateTmpMatrix.SRMultiply(matrix_parentTransform, true); ////_matrix_TF_Cal_ToWorld = _calculateTmpMatrix.MtrxToSpace; _matrix_TF_ParentWorld.SetMatrix(matrix_parentTransform); }
public void SetModifiedTransform(apMatrix matrix_modified) { ////_calculateTmpMatrix_Local.SRMultiply(matrix_modified, true);//Parent //_calculateTmpMatrix_Local.SRMultiply(matrix_modified, false);//Child //_matrix_TF_Cal_Local = _calculateTmpMatrix_Local.MtrxToSpace; _matrix_TF_LocalModified.SetMatrix(matrix_modified); }
// Functions //-------------------------------------------- public void ReadyToCalculate() { _matrix.MakeMatrix(); //변경 //[Parent World x To Parent x Local TF] 조합으로 변경 if (_matrix_TF_ParentWorld == null) { _matrix_TF_ParentWorld = new apMatrix(); } if (_matrix_TF_ParentWorldWithoutMod == null) { _matrix_TF_ParentWorldWithoutMod = new apMatrix(); } if (_matrix_TF_ToParent == null) { _matrix_TF_ToParent = new apMatrix(); } if (_matrix_TF_LocalModified == null) { _matrix_TF_LocalModified = new apMatrix(); } if (_matrix_TFResult_World == null) { _matrix_TFResult_World = new apMatrix(); } if (_matrix_TFResult_WorldWithoutMod == null) { _matrix_TFResult_WorldWithoutMod = new apMatrix(); } if (_invMatrix_TFResult_World == null) { _invMatrix_TFResult_World = new apMatrix(); } if (_invMatrix_TFResult_WorldWithoutMod == null) { _invMatrix_TFResult_WorldWithoutMod = new apMatrix(); } _matrix_TF_ParentWorld.SetIdentity(); _matrix_TF_ParentWorldWithoutMod.SetIdentity(); _matrix_TF_ToParent.SetIdentity(); _matrix_TF_LocalModified.SetIdentity(); //ToParent는 Pivot이므로 고정 _matrix_TF_ToParent.SetMatrix(_matrix); _matrix_TFResult_World.SetIdentity(); _matrix_TFResult_WorldWithoutMod.SetIdentity(); _invMatrix_TFResult_World.SetIdentity(); _invMatrix_TFResult_WorldWithoutMod.SetIdentity(); CalculatedLog.ReadyToRecord(); }
// Functions //-------------------------------------------- public void ReadyToCalculate() { _matrix.MakeMatrix(); //_matrix_TF_Cal_Parent = apMatrix3x3.identity; //_matrix_TF_Cal_Local = _matrix.MtrxToSpace; //if(_calculateTmpMatrix == null) //{ // _calculateTmpMatrix = new apMatrix(); //} //_calculateTmpMatrix.SetIdentity(); //_calculateTmpMatrix.SetMatrix(_matrix); //if(_calculateTmpMatrix_Local == null) //{ // _calculateTmpMatrix_Local = new apMatrix(); //} //_calculateTmpMatrix_Local.SetIdentity(); //_calculateTmpMatrix_Local.SetMatrix(_matrix); //변경 //[Parent World x To Parent x Local TF] 조합으로 변경 if (_matrix_TF_ParentWorld == null) { _matrix_TF_ParentWorld = new apMatrix(); } if (_matrix_TF_ToParent == null) { _matrix_TF_ToParent = new apMatrix(); } if (_matrix_TF_LocalModified == null) { _matrix_TF_LocalModified = new apMatrix(); } if (_matrix_TFResult_World == null) { _matrix_TFResult_World = new apMatrix(); } if (_matrix_TFResult_WorldWithoutMod == null) { _matrix_TFResult_WorldWithoutMod = new apMatrix(); } _matrix_TF_ParentWorld.SetIdentity(); _matrix_TF_ToParent.SetIdentity(); _matrix_TF_LocalModified.SetIdentity(); //ToParent는 Pivot이므로 고정 _matrix_TF_ToParent.SetMatrix(_matrix); _matrix_TFResult_World.SetIdentity(); _matrix_TFResult_WorldWithoutMod.SetIdentity(); }
// Functions //------------------------------------------------------ // Bone -> File //------------------------------------------------------ public void SetBone(int unitID, apBone bone) { _unitID = unitID; _uniqueID = bone._uniqueID; _name = bone._name; _defaultMatrix.SetMatrix(bone._defaultMatrix); _localMatrix.SetMatrix(bone._localMatrix); _worldMatrix.SetMatrix(bone._worldMatrix); _targetBone = bone; //<<Export할때도 연결해주자 }
//Link 함수의 내용은 Bake 시에 진행해야한다. public void Bake(apBone bone) { _uniqueID = bone._uniqueID; _meshGroupID = bone._meshGroupID; _defaultMatrix.SetMatrix(bone._defaultMatrix); _deltaPos = Vector2.zero; _deltaAngle = 0.0f; _deltaScale = Vector2.one; _localMatrix.SetIdentity(); _worldMatrix.SetIdentity(); _color = bone._color; _shapeWidth = bone._shapeWidth; _shapeLength = bone._shapeLength; _shapeTaper = bone._shapeTaper; _optionLocalMove = bone._optionLocalMove; _optionIK = bone._optionIK; _isIKTail = bone._isIKTail; _IKTargetBoneID = bone._IKTargetBoneID; _IKTargetBone = null; //<<나중에 링크 _IKNextChainedBoneID = bone._IKNextChainedBoneID; _IKNextChainedBone = null; //<<나중에 링크 _IKHeaderBoneID = bone._IKHeaderBoneID; _IKHeaderBone = null; //<<나중에 링크 _isIKAngleRange = bone._isIKAngleRange; _IKAngleRange_Lower = bone._IKAngleRange_Lower; _IKAngleRange_Upper = bone._IKAngleRange_Upper; _IKAnglePreferred = bone._IKAnglePreferred; _isIKCalculated = false; _IKRequestAngleResult = 0.0f; _transformLocalMatrix.SetIdentity(); }
public void SetMatrixWrap(apMatrix matrixWrap, CalculateType calculateType, bool isWeighted, float weight) { _valueType = UnitValueType.MatrixWrap; if (_val_MatrixWrap == null) { _val_MatrixWrap = new apMatrix(matrixWrap); //<<복사를 하자 } else { _val_MatrixWrap.SetMatrix(matrixWrap); } _calculateType = calculateType; _isWeighted = isWeighted; _weight = weight; }
public void MakeTransformMatrix() { //[R] _matrix_TFResult_World.RMultiply(_matrix_TF_ToParent); _matrix_TFResult_World.RMultiply(_matrix_TF_LocalModified); _matrix_TFResult_World.RMultiply(_matrix_TF_ParentWorld); _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ToParent); _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ParentWorld); //Inverse는 반대로 계산한다. _invMatrix_TFResult_World.SetMatrix(_matrix_TF_ParentWorld); _invMatrix_TFResult_World.RInverse(_matrix_TF_LocalModified); _invMatrix_TFResult_World.RInverse(_matrix_TF_ToParent); _invMatrix_TFResult_WorldWithoutMod.SetMatrix(_matrix_TF_ParentWorldWithoutMod); _invMatrix_TFResult_WorldWithoutMod.RInverse(_matrix_TF_ToParent); }
public override bool Save(object target, string strParam) { base.Save(target, strParam); apModifiedBone modBone = target as apModifiedBone; if (modBone == null) { return(false); } _key_MeshGroupOfMod = modBone._meshGroup_Modifier; _key_MeshGroupOfBone = modBone._meshGroup_Bone; _key_Bone = modBone._bone; _transformMatrix.SetMatrix(modBone._transformMatrix); return(true); }
/// <summary> /// CalculateStack을 업데이트 한다. /// Pre-Update이다. Rigging, VertWorld는 제외된다. /// </summary> public void UpdateCalculate_Pre() { //#if UNITY_EDITOR // Profiler.BeginSample("Transform - 1. Stack Calculate"); //#endif //1. Calculated Stack 업데이트 if (_calculatedStack != null) { _calculatedStack.Calculate_Pre(); } //#if UNITY_EDITOR // Profiler.EndSample(); //#endif //#if UNITY_EDITOR // Profiler.BeginSample("Transform - 2. Matrix / Color"); //#endif //2. Calculated의 값 적용 + 계층적 Matrix 적용 if (CalculatedStack.MeshWorldMatrixWrap != null) { //변경전 //_calclateTmpMatrix.SRMultiply(_calculatedStack.MeshWorldMatrixWrap, true); //_matrix_TF_Cal_ToWorld = _calculateTmpMatrix.MtrxToSpace; //변경후 _matrix_TF_LocalModified.SetMatrix(_calculatedStack.MeshWorldMatrixWrap); //if(_calculatedStack.MeshWorldMatrixWrap.Scale2.magnitude < 0.8f) //{ // Debug.Log(name + " : Low Scale : " + _calculatedStack.MeshWorldMatrixWrap.Scale2); //} } if (CalculatedStack.IsAnyColorCalculated) { _meshColor2X = CalculatedStack.MeshColor; _isVisible = CalculatedStack.IsMeshVisible; _isAnyColorCalculated = true; } else { _meshColor2X = _meshColor2X_Default; _isVisible = _isVisible_Default; } if (!_isVisible) { _meshColor2X.a = 0.0f; _isAnyColorCalculated = true; } //추가 11.30 : Extra Option if (_calculatedStack.IsExtraDepthChanged) { if (_func_ExtraDepthChanged != null) { _func_ExtraDepthChanged(this, _calculatedStack.ExtraDeltaDepth); } } if (_calculatedStack.IsExtraTextureChanged) { _isExtraTextureChanged = true; _extraTextureData = _calculatedStack.ExtraTextureData; if (_extraTextureData == null) { _isExtraTextureChanged = false; } } if (_isExtraTextureChanged_Prev != _isExtraTextureChanged || _extraTextureData_Prev != _extraTextureData) { #if UNITY_EDITOR if (Application.isPlaying) { #endif //Extra-Texture 이벤트가 발생하거나 해지되어서 상태가 바뀌었을 경우 //또는 새로운 텍스쳐가 발생했을 경우 if (_childMesh != null) { if (_isExtraTextureChanged) { //> 텍스쳐 교체 이벤트가 발생했다. //현재 처리중인 텍스쳐를 먼저 저장한 뒤, 교체 _extraDefaultTexture = _childMesh.GetCurrentProcessedTexture(); _childMesh.SetExtraChangedTexture(_extraTextureData._texture); } else { //>텍스쳐를 해지해야한다. 저장했던 값으로 되돌린다. _childMesh.SetExtraChangedTexture(_extraDefaultTexture); } } #if UNITY_EDITOR } #endif _isExtraTextureChanged_Prev = _isExtraTextureChanged; if (_isExtraTextureChanged) { _extraTextureData_Prev = _extraTextureData; } else { _extraTextureData_Prev = null; } } if (_parentTransform != null) { //변경 전 //_calculateTmpMatrix.SRMultiply(_parentTransform.CalculatedTmpMatrix, true); //_matrix_TF_Cal_ToWorld = _calculateTmpMatrix.MtrxToSpace; //변경 후 _matrix_TF_ParentWorld.SetMatrix(_parentTransform._matrix_TFResult_World); _matrix_TF_ParentWorld_NonModified.SetMatrix(_parentTransform._matrix_TFResult_WorldWithoutMod); //색상은 2X 방식의 Add _meshColor2X.r = Mathf.Clamp01(((float)(_meshColor2X.r) - 0.5f) + ((float)(_parentTransform._meshColor2X.r) - 0.5f) + 0.5f); _meshColor2X.g = Mathf.Clamp01(((float)(_meshColor2X.g) - 0.5f) + ((float)(_parentTransform._meshColor2X.g) - 0.5f) + 0.5f); _meshColor2X.b = Mathf.Clamp01(((float)(_meshColor2X.b) - 0.5f) + ((float)(_parentTransform._meshColor2X.b) - 0.5f) + 0.5f); _meshColor2X.a *= _parentTransform._meshColor2X.a; if (_parentTransform._isAnyColorCalculated) { _isAnyColorCalculated = true; } } if (_meshColor2X.a < VISIBLE_ALPHA //|| !CalculatedStack.IsMeshVisible ) { _isVisible = false; _meshColor2X.a = 0.0f; _isAnyColorCalculated = true; } //MakeTransformMatrix(); < 이 함수 부분 //World Matrix를 만든다. _matrix_TFResult_World.RMultiply(_matrix_TF_ToParent); //변경 : ToParent -> LocalModified -> ParentWorld 순으로 바꾼다. _matrix_TFResult_World.RMultiply(_matrix_TF_LocalModified); //<<[R] //_matrix_TFResult_World.RMultiply(_matrix_TF_ToParent);//<<[R] _matrix_TFResult_World.RMultiply(_matrix_TF_ParentWorld); //<<[R] //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ToParent, true);//ToParent는 넣지 않는다. //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ParentWorld, true);//<<[SR] //Without Mod는 계산하지 않았을 경우에만 계산한다. //바뀌지 않으므로 if (!_isCalculateWithoutMod) { _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ToParent); //<<[R] _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ParentWorld_NonModified); //<<[R] //리깅용 단축식을 추가한다. if (_childMesh != null) { _vertLocal2MeshWorldMatrix = _matrix_TFResult_WorldWithoutMod.MtrxToSpace; _vertLocal2MeshWorldMatrix *= _childMesh._matrix_Vert2Mesh; _vertWorld2MeshLocalMatrix = _childMesh._matrix_Vert2Mesh_Inverse; _vertWorld2MeshLocalMatrix *= _matrix_TFResult_WorldWithoutMod.MtrxToLowerSpace; _vertMeshWorldNoModMatrix = _matrix_TFResult_WorldWithoutMod.MtrxToSpace; _vertMeshWorldNoModInverseMatrix = _matrix_TFResult_WorldWithoutMod.MtrxToLowerSpace; } _isCalculateWithoutMod = true; } //_convert2TargetMatrix4x4 = Matrix4x4.identity; //_convert2TargetMatrix3x3 = apMatrix3x3.identity; _isCamOrthoCorrection = false; if (_portrait._billboardType != apPortrait.BILLBOARD_TYPE.None && _childMesh != null) { Camera curCamera = _portrait.GetCamera(); if (curCamera != null && !curCamera.orthographic) { //Perspective 카메라라면 Vector3 pos_Cam = curCamera.worldToCameraMatrix.MultiplyPoint3x4(_childMesh.transform.position); //Vector3 pos_Cam = (curCamera.worldToCameraMatrix * transform.localToWorldMatrix).MultiplyPoint3x4(new Vector3(_matrix_TFResult_World._pos.x, _matrix_TFResult_World._pos.y, 0)); float zDepth = pos_Cam.z; float zRatio = zDepth / _portrait.GetZDepth(); //Debug.Log("pos_Cam : " + pos_Cam + " / " + zRatio); //transform.tr//>>TODO _isCamOrthoCorrection = true; Matrix4x4 orthoConvertMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(zRatio, zRatio, 1)); _convert2TargetMatrix4x4 = _childMesh.transform.worldToLocalMatrix * curCamera.cameraToWorldMatrix * orthoConvertMatrix * curCamera.worldToCameraMatrix * _childMesh.transform.localToWorldMatrix; _convert2TargetMatrix3x3 = apMatrix3x3.identity; _convert2TargetMatrix3x3._m00 = _convert2TargetMatrix4x4.m00; _convert2TargetMatrix3x3._m01 = _convert2TargetMatrix4x4.m01; _convert2TargetMatrix3x3._m02 = _convert2TargetMatrix4x4.m03; _convert2TargetMatrix3x3._m10 = _convert2TargetMatrix4x4.m10; _convert2TargetMatrix3x3._m11 = _convert2TargetMatrix4x4.m11; _convert2TargetMatrix3x3._m12 = _convert2TargetMatrix4x4.m13; _convert2TargetMatrix3x3._m20 = _convert2TargetMatrix4x4.m30; _convert2TargetMatrix3x3._m21 = _convert2TargetMatrix4x4.m31; _convert2TargetMatrix3x3._m22 = _convert2TargetMatrix4x4.m23; //Debug.Log("_convert2TargetMatrix4x4 : \n " + _convert2TargetMatrix4x4.ToString() + "\n" + "_convert2TargetMatrix3x3 : \n " + _convert2TargetMatrix3x3.ToString()); } } //처리된 TRS _updatedWorldPos_NoRequest.x = _matrix_TFResult_World._pos.x; _updatedWorldPos_NoRequest.y = _matrix_TFResult_World._pos.y; _updatedWorldAngle_NoRequest = _matrix_TFResult_World._angleDeg; _updatedWorldScale_NoRequest.x = _matrix_TFResult_World._scale.x; _updatedWorldScale_NoRequest.y = _matrix_TFResult_World._scale.y; _updatedWorldPos = _updatedWorldPos_NoRequest; _updatedWorldAngle = _updatedWorldAngle_NoRequest; _updatedWorldScale = _updatedWorldScale_NoRequest; //스크립트로 외부에서 제어한 경우 if (_isExternalUpdate_Position) { _updatedWorldPos.x = (_exUpdate_Pos.x * _externalUpdateWeight) + (_updatedWorldPos.x * (1.0f - _externalUpdateWeight)); _updatedWorldPos.y = (_exUpdate_Pos.y * _externalUpdateWeight) + (_updatedWorldPos.y * (1.0f - _externalUpdateWeight)); } if (_isExternalUpdate_Rotation) { _updatedWorldAngle = (_exUpdate_Angle * _externalUpdateWeight) + (_updatedWorldAngle * (1.0f - _externalUpdateWeight)); } if (_isExternalUpdate_Scaling) { _updatedWorldScale.x = (_exUpdate_Scale.x * _externalUpdateWeight) + (_updatedWorldScale.x * (1.0f - _externalUpdateWeight)); _updatedWorldScale.y = (_exUpdate_Scale.y * _externalUpdateWeight) + (_updatedWorldScale.y * (1.0f - _externalUpdateWeight)); } if (_isExternalUpdate_Position || _isExternalUpdate_Rotation || _isExternalUpdate_Scaling) { //WorldMatrix를 갱신해주자 _matrix_TFResult_World.SetTRS(_updatedWorldPos.x, _updatedWorldPos.y, _updatedWorldAngle, _updatedWorldScale.x, _updatedWorldScale.y); _isExternalUpdate_Position = false; _isExternalUpdate_Rotation = false; _isExternalUpdate_Scaling = false; } //추가 : 소켓도 만들어준다. //Vert World를 아직 계산하지 않았지만 Socket 처리에는 문제가 없다. if (_socketTransform != null) { _socketTransform.localPosition = new Vector3(_matrix_TFResult_World._pos.x, _matrix_TFResult_World._pos.y, 0); _socketTransform.localRotation = Quaternion.Euler(0.0f, 0.0f, _matrix_TFResult_World._angleDeg); _socketTransform.localScale = new Vector3(_matrix_TFResult_World._scale.x, _matrix_TFResult_World._scale.y, 1.0f); } //#if UNITY_EDITOR // Profiler.EndSample(); //#endif //[MeshUpdate]는 Post Update로 전달 //3. 자식 호출 //자식 객체도 업데이트를 한다. if (_childTransforms != null) { for (int i = 0; i < _childTransforms.Length; i++) { _childTransforms[i].UpdateCalculate_Pre(); } } }
/// <summary> /// 4) World Matrix를 만든다. /// 이 함수는 Parent의 MeshGroupTransform이 연산된 후 -> Vertex가 연산되기 전에 호출되어야 한다. /// </summary> public void MakeWorldMatrix(bool isRecursive) { _localMatrix.SetIdentity(); _localMatrix._pos = _deltaPos; _localMatrix._angleDeg = _deltaAngle; _localMatrix._scale.x = _deltaScale.x; _localMatrix._scale.y = _deltaScale.y; _localMatrix.MakeMatrix(); //World Matrix = ParentMatrix x LocalMatrix //Root인 경우에는 MeshGroup의 Matrix를 이용하자 //_invWorldMatrix_NonModified.SetIdentity(); if (_parentBone == null) { _worldMatrix.SetMatrix(_defaultMatrix); _worldMatrix.Add(_localMatrix); _worldMatrix_NonModified.SetMatrix(_defaultMatrix); //Local Matrix 없이 Default만 지정 if (_parentOptTransform != null) { //Debug.Log("SetParentOptTransform Matrix : [" + _parentOptTransform.transform.name + "] : " + _parentOptTransform._matrix_TFResult_World.Scale2); //Non Modified도 동일하게 적용 //렌더유닛의 WorldMatrix를 넣어주자 _worldMatrix.RMultiply(_parentOptTransform._matrix_TFResult_World); //RenderUnit의 WorldMatrixWrap의 Opt 버전 _worldMatrix_NonModified.RMultiply(_parentOptTransform._matrix_TFResult_WorldWithoutMod); } } else { _worldMatrix.SetMatrix(_defaultMatrix); _worldMatrix.Add(_localMatrix); _worldMatrix.RMultiply(_parentBone._worldMatrix); _worldMatrix_NonModified.SetMatrix(_defaultMatrix); //Local Matrix 없이 Default만 지정 _worldMatrix_NonModified.RMultiply(_parentBone._worldMatrix_NonModified); } //World Matrix는 MeshGroup과 동일한 Space의 값을 가진다. //그러나 실제로 Bone World Matrix는 //Root - MeshGroup...(Rec) - Bone Group - Bone.. (Rec <- 여기) //의 레벨을 가진다. //Root 밑으로는 모두 World에 대해서 동일한 Space를 가지므로 //Root를 찾아서 Scale을 제어하자...? //일단 Parent에서 빼두자 //_transformLocalMatrix.SetMatrix(_worldMatrix); #if UNITY_EDITOR _shapePoint_End = new Vector2(0.0f, _shapeLength); _shapePoint_Mid1 = new Vector2(-_shapeWidth * 0.5f, _shapeLength * 0.2f); _shapePoint_Mid2 = new Vector2(_shapeWidth * 0.5f, _shapeLength * 0.2f); float taperRatio = Mathf.Clamp01((float)(100 - _shapeTaper) / 100.0f); _shapePoint_End1 = new Vector2(-_shapeWidth * 0.5f * taperRatio, _shapeLength); _shapePoint_End2 = new Vector2(_shapeWidth * 0.5f * taperRatio, _shapeLength); _shapePoint_End = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_End); _shapePoint_Mid1 = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_Mid1); _shapePoint_Mid2 = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_Mid2); _shapePoint_End1 = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_End1); _shapePoint_End2 = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_End2); #endif if (_socketTransform != null) { //소켓을 업데이트 하자 _socketTransform.localPosition = new Vector3(_worldMatrix._pos.x, _worldMatrix._pos.y, 0); _socketTransform.localRotation = Quaternion.Euler(0.0f, 0.0f, _worldMatrix._angleDeg); _socketTransform.localScale = _worldMatrix._scale; } //if (string.Equals(name, "Bone 2 Debug")) //{ // //디버그를 해보자 // Debug.Log("------- Bone Matrix [" + name + "] ------- (Runtime)"); // Debug.Log("Default Matrix [" + _defaultMatrix.ToString() + "]"); // Debug.Log("Local Matrix [" + _localMatrix.ToString() + "]"); // if (_parentBone != null) // { // Debug.Log("Parent(" + _parentBone.name + ")"); // Debug.Log(">> World Matrix [" + _parentBone._worldMatrix.ToString() + "]"); // Debug.Log(">> World Matrix No Mod [" + _parentBone._worldMatrix_NonModified.ToString() + "]"); // } // Debug.Log("World Matrix [" + _worldMatrix.ToString() + "]"); // Debug.Log("World Matrix No Mod [" + _worldMatrix_NonModified.ToString() + "]"); // Debug.Log("-----------------------------------------"); //} //Child도 호출해준다. if (isRecursive && _childBones != null) { for (int i = 0; i < _childBones.Length; i++) { _childBones[i].MakeWorldMatrix(true); } } }
// Functions //---------------------------------------------- // TF/Bone -> File //---------------------------------------------- public void SetSubData(int unitID, apTransform_Mesh meshTransform, apTransform_MeshGroup meshGroupTransform, apBone bone, apRetargetSubUnit parentRetargetUnit) { _unitID = unitID; _parentUnitID = -1; _childUnitIDs.Clear(); _parentUnit = null; _childUnits.Clear(); if (meshTransform != null) { _type = TYPE.MeshTransform; _uniqueID = meshTransform._transformUniqueID; _name = meshTransform._nickName; _defaultMatrix.SetMatrix(meshTransform._matrix); _defaultColor = meshTransform._meshColor2X_Default; _isVisible = meshTransform._isVisible_Default; } else if (meshGroupTransform != null) { _type = TYPE.MeshGroupTransform; _uniqueID = meshGroupTransform._transformUniqueID; _name = meshGroupTransform._nickName; _defaultMatrix.SetMatrix(meshGroupTransform._matrix); _defaultColor = meshGroupTransform._meshColor2X_Default; _isVisible = meshGroupTransform._isVisible_Default; } else if (bone != null) { _type = TYPE.Bone; _uniqueID = bone._uniqueID; _name = bone._name; _defaultMatrix.SetMatrix(bone._defaultMatrix); _defaultColor = Color.white; _isVisible = true; } else { Debug.LogError("Wrong Sub Unit"); return; } if (parentRetargetUnit != null) { //Parent와 연결한다. _parentUnitID = parentRetargetUnit._unitID; _parentUnit = parentRetargetUnit; parentRetargetUnit._childUnitIDs.Add(_unitID); parentRetargetUnit._childUnits.Add(this); } }
/// <summary> /// Parent의 Matrix를 추가한다. (Parent x This) /// </summary> /// <param name="matrix_parentTransform"></param> //public void AddWorldMatrix_Parent(apMatrix3x3 matrix_parentTransform) public void AddWorldMatrix_Parent(apMatrix matrix_parentTransform, apMatrix matrix_parentTransformNoMod) { _matrix_TF_ParentWorld.SetMatrix(matrix_parentTransform); _matrix_TF_ParentWorldWithoutMod.SetMatrix(matrix_parentTransformNoMod); }
public void SetModifiedTransform(apMatrix matrix_modified, apCalculatedLog calResultStack_CalLog) { _matrix_TF_LocalModified.SetMatrix(matrix_modified); CalculatedLog.LinkLog_CalculateResultStackTF(calResultStack_CalLog); }
// Functions //--------------------------------------------------- // Bone to File //--------------------------------------------------- public void SetBone(int unitID, apBone bone, Dictionary <int, int> boneID2UnitIDs) { _unitID = unitID; _boneUniqueID = bone._uniqueID; _linkedBone = bone; _name = bone._name; if (bone._parentBoneID < 0) { _parentUnitID = -1; } else { _parentUnitID = boneID2UnitIDs[bone._parentBoneID]; } _level = bone._level; _depth = bone._depth; _childUnitID.Clear(); if (bone._childBoneIDs != null) { for (int i = 0; i < bone._childBoneIDs.Count; i++) { int childID = bone._childBoneIDs[i]; if (childID >= 0) { _childUnitID.Add(boneID2UnitIDs[childID]); } } } _defaultMatrix.SetMatrix(bone._defaultMatrix); _color = bone._color; _shapeWidth = bone._shapeWidth; _shapeLength = bone._shapeLength; _shapeTaper = bone._shapeTaper; _optionIK = bone._optionIK; _isIKTail = bone._isIKTail; _IKTargetBoneUnitID = -1; if (bone._IKTargetBoneID >= 0) { _IKTargetBoneUnitID = boneID2UnitIDs[bone._IKTargetBoneID]; } _IKNextChainedBoneUnitID = -1; if (bone._IKNextChainedBoneID >= 0) { _IKNextChainedBoneUnitID = boneID2UnitIDs[bone._IKNextChainedBoneID]; } _IKHeaderBoneUnitID = -1; if (bone._IKHeaderBoneID >= 0) { _IKHeaderBoneUnitID = boneID2UnitIDs[bone._IKHeaderBoneID]; } _isIKAngleRange = bone._isIKAngleRange; _IKAngleRange_Lower = bone._IKAngleRange_Lower; _IKAngleRange_Upper = bone._IKAngleRange_Upper; _IKAnglePreferred = bone._IKAnglePreferred; _isSocketEnabled = false; }
/// <summary> /// Bake를 위해서 BoneMatrix를 초기화한다. /// </summary> /// <param name="isRecursive"></param> public void ResetBoneMatrixForBake(bool isRecursive) { _deltaPos = Vector2.zero; _deltaAngle = 0.0f; _deltaScale = Vector2.one; _localMatrix.SetIdentity(); _worldMatrix.SetIdentity(); _worldMatrix_NonModified.SetIdentity(); _vertWorld2BoneModWorldMatrix.SetIdentity(); if (_parentBone == null) { _worldMatrix.SetMatrix(_defaultMatrix); _worldMatrix.Add(_localMatrix); _worldMatrix_NonModified.SetMatrix(_defaultMatrix); //Local Matrix 없이 Default만 지정 if (_parentOptTransform != null) { //Debug.Log("SetParentOptTransform Matrix : [" + _parentOptTransform.transform.name + "] : " + _parentOptTransform._matrix_TFResult_World.Scale2); //Non Modified도 동일하게 적용 //렌더유닛의 WorldMatrix를 넣어주자 _worldMatrix.RMultiply(_parentOptTransform._matrix_TFResult_WorldWithoutMod); //RenderUnit의 WorldMatrixWrap의 Opt 버전 _worldMatrix_NonModified.RMultiply(_parentOptTransform._matrix_TFResult_WorldWithoutMod); } } else { _worldMatrix.SetMatrix(_defaultMatrix); _worldMatrix.Add(_localMatrix); _worldMatrix.RMultiply(_parentBone._worldMatrix_NonModified); _worldMatrix_NonModified.SetMatrix(_defaultMatrix); //Local Matrix 없이 Default만 지정 _worldMatrix_NonModified.RMultiply(_parentBone._worldMatrix_NonModified); } _worldMatrix.SetMatrix(_worldMatrix_NonModified); _vertWorld2BoneModWorldMatrix = _worldMatrix_NonModified.MtrxToSpace; _vertWorld2BoneModWorldMatrix *= _worldMatrix_NonModified.MtrxToLowerSpace; //Debug.Log("Reset Bone Matrix [" + this.name + "]"); //Debug.Log("World Matrix [ " + _worldMatrix.ToString() + "]"); if (isRecursive) { if (_childBones != null && _childBones.Length > 0) { for (int i = 0; i < _childBones.Length; i++) { _childBones[i].ResetBoneMatrixForBake(true); } } } }
/// <summary> /// CalculateStack을 업데이트 한다. /// Pre-Update이다. Rigging, VertWorld는 제외된다. /// </summary> public void UpdateCalculate_Pre() { //#if UNITY_EDITOR // Profiler.BeginSample("Transform - 1. Stack Calculate"); //#endif //1. Calculated Stack 업데이트 if (_calculatedStack != null) { _calculatedStack.Calculate_Pre(); } //#if UNITY_EDITOR // Profiler.EndSample(); //#endif //#if UNITY_EDITOR // Profiler.BeginSample("Transform - 2. Matrix / Color"); //#endif //2. Calculated의 값 적용 + 계층적 Matrix 적용 if (CalculatedStack.MeshWorldMatrixWrap != null) { //변경전 //_calclateTmpMatrix.SRMultiply(_calculatedStack.MeshWorldMatrixWrap, true); //_matrix_TF_Cal_ToWorld = _calculateTmpMatrix.MtrxToSpace; //변경후 _matrix_TF_LocalModified.SetMatrix(_calculatedStack.MeshWorldMatrixWrap); //if(_calculatedStack.MeshWorldMatrixWrap.Scale2.magnitude < 0.8f) //{ // Debug.Log(name + " : Low Scale : " + _calculatedStack.MeshWorldMatrixWrap.Scale2); //} } if (CalculatedStack.IsAnyColorCalculated) { _meshColor2X = CalculatedStack.MeshColor; _isVisible = CalculatedStack.IsMeshVisible; _isAnyColorCalculated = true; } else { _meshColor2X = _meshColor2X_Default; _isVisible = _isVisible_Default; } if (!_isVisible) { _meshColor2X.a = 0.0f; _isAnyColorCalculated = true; } if (_parentTransform != null) { //변경 전 //_calculateTmpMatrix.SRMultiply(_parentTransform.CalculatedTmpMatrix, true); //_matrix_TF_Cal_ToWorld = _calculateTmpMatrix.MtrxToSpace; //변경 후 _matrix_TF_ParentWorld.SetMatrix(_parentTransform._matrix_TFResult_World); _matrix_TF_ParentWorld_NonModified.SetMatrix(_parentTransform._matrix_TFResult_WorldWithoutMod); //색상은 2X 방식의 Add _meshColor2X.r = Mathf.Clamp01(((float)(_meshColor2X.r) - 0.5f) + ((float)(_parentTransform._meshColor2X.r) - 0.5f) + 0.5f); _meshColor2X.g = Mathf.Clamp01(((float)(_meshColor2X.g) - 0.5f) + ((float)(_parentTransform._meshColor2X.g) - 0.5f) + 0.5f); _meshColor2X.b = Mathf.Clamp01(((float)(_meshColor2X.b) - 0.5f) + ((float)(_parentTransform._meshColor2X.b) - 0.5f) + 0.5f); _meshColor2X.a *= _parentTransform._meshColor2X.a; if (_parentTransform._isAnyColorCalculated) { _isAnyColorCalculated = true; } } if (_meshColor2X.a < VISIBLE_ALPHA //|| !CalculatedStack.IsMeshVisible ) { _isVisible = false; _meshColor2X.a = 0.0f; _isAnyColorCalculated = true; } //MakeTransformMatrix(); < 이 함수 부분 //World Matrix를 만든다. _matrix_TFResult_World.RMultiply(_matrix_TF_ToParent); //변경 : ToParent -> LocalModified -> ParentWorld 순으로 바꾼다. _matrix_TFResult_World.RMultiply(_matrix_TF_LocalModified); //<<[R] //_matrix_TFResult_World.RMultiply(_matrix_TF_ToParent);//<<[R] _matrix_TFResult_World.RMultiply(_matrix_TF_ParentWorld); //<<[R] //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ToParent, true);//ToParent는 넣지 않는다. //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ParentWorld, true);//<<[SR] //Without Mod는 계산하지 않았을 경우에만 계산한다. //바뀌지 않으므로 if (!_isCalculateWithoutMod) { _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ToParent); //<<[R] _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ParentWorld_NonModified); //<<[R] //리깅용 단축식을 추가한다. if (_childMesh != null) { _vertLocal2MeshWorldMatrix = _matrix_TFResult_WorldWithoutMod.MtrxToSpace; _vertLocal2MeshWorldMatrix *= _childMesh._matrix_Vert2Mesh; _vertWorld2MeshLocalMatrix = _childMesh._matrix_Vert2Mesh_Inverse; _vertWorld2MeshLocalMatrix *= _matrix_TFResult_WorldWithoutMod.MtrxToLowerSpace; _vertMeshWorldNoModMatrix = _matrix_TFResult_WorldWithoutMod.MtrxToSpace; _vertMeshWorldNoModInverseMatrix = _matrix_TFResult_WorldWithoutMod.MtrxToLowerSpace; } _isCalculateWithoutMod = true; } //처리된 TRS _updatedWorldPos_NoRequest.x = _matrix_TFResult_World._pos.x; _updatedWorldPos_NoRequest.y = _matrix_TFResult_World._pos.y; _updatedWorldAngle_NoRequest = _matrix_TFResult_World._angleDeg; _updatedWorldScale_NoRequest.x = _matrix_TFResult_World._scale.x; _updatedWorldScale_NoRequest.y = _matrix_TFResult_World._scale.y; _updatedWorldPos = _updatedWorldPos_NoRequest; _updatedWorldAngle = _updatedWorldAngle_NoRequest; _updatedWorldScale = _updatedWorldScale_NoRequest; //스크립트로 외부에서 제어한 경우 if (_isExternalUpdate_Position) { _updatedWorldPos.x = (_exUpdate_Pos.x * _externalUpdateWeight) + (_updatedWorldPos.x * (1.0f - _externalUpdateWeight)); _updatedWorldPos.y = (_exUpdate_Pos.y * _externalUpdateWeight) + (_updatedWorldPos.y * (1.0f - _externalUpdateWeight)); } if (_isExternalUpdate_Rotation) { _updatedWorldAngle = (_exUpdate_Angle * _externalUpdateWeight) + (_updatedWorldAngle * (1.0f - _externalUpdateWeight)); } if (_isExternalUpdate_Scaling) { _updatedWorldScale.x = (_exUpdate_Scale.x * _externalUpdateWeight) + (_updatedWorldScale.x * (1.0f - _externalUpdateWeight)); _updatedWorldScale.y = (_exUpdate_Scale.y * _externalUpdateWeight) + (_updatedWorldScale.y * (1.0f - _externalUpdateWeight)); } if (_isExternalUpdate_Position || _isExternalUpdate_Rotation || _isExternalUpdate_Scaling) { //WorldMatrix를 갱신해주자 _matrix_TFResult_World.SetTRS(_updatedWorldPos.x, _updatedWorldPos.y, _updatedWorldAngle, _updatedWorldScale.x, _updatedWorldScale.y); _isExternalUpdate_Position = false; _isExternalUpdate_Rotation = false; _isExternalUpdate_Scaling = false; } //추가 : 소켓도 만들어준다. //Vert World를 아직 계산하지 않았지만 Socket 처리에는 문제가 없다. if (_socketTransform != null) { _socketTransform.localPosition = new Vector3(_matrix_TFResult_World._pos.x, _matrix_TFResult_World._pos.y, 0); _socketTransform.localRotation = Quaternion.Euler(0.0f, 0.0f, _matrix_TFResult_World._angleDeg); _socketTransform.localScale = new Vector3(_matrix_TFResult_World._scale.x, _matrix_TFResult_World._scale.y, 1.0f); } //#if UNITY_EDITOR // Profiler.EndSample(); //#endif //[MeshUpdate]는 Post Update로 전달 //3. 자식 호출 //자식 객체도 업데이트를 한다. if (_childTransforms != null) { for (int i = 0; i < _childTransforms.Length; i++) { _childTransforms[i].UpdateCalculate_Pre(); } } }
/// <summary> /// CalculateStack을 업데이트 한다. /// Pre-Update이다. Rigging, VertWorld는 제외된다. /// </summary> public void UpdateCalculate_Pre() { #if UNITY_EDITOR Profiler.BeginSample("Transform - 1. Stack Calculate"); #endif //1. Calculated Stack 업데이트 if (_calculatedStack != null) { _calculatedStack.Calculate_Pre(); } #if UNITY_EDITOR Profiler.EndSample(); #endif #if UNITY_EDITOR Profiler.BeginSample("Transform - 2. Matrix / Color"); #endif //2. Calculated의 값 적용 + 계층적 Matrix 적용 if (_calculatedStack.MeshWorldMatrixWrap != null) { //변경전 //_calclateTmpMatrix.SRMultiply(_calculatedStack.MeshWorldMatrixWrap, true); //_matrix_TF_Cal_ToWorld = _calculateTmpMatrix.MtrxToSpace; //변경후 _matrix_TF_LocalModified.SetMatrix(_calculatedStack.MeshWorldMatrixWrap); //if(_calculatedStack.MeshWorldMatrixWrap.Scale2.magnitude < 0.8f) //{ // Debug.Log(name + " : Low Scale : " + _calculatedStack.MeshWorldMatrixWrap.Scale2); //} } if (CalculatedStack.IsAnyColorCalculated) { _meshColor2X = CalculatedStack.MeshColor; _isVisible = CalculatedStack.IsMeshVisible; } else { _meshColor2X = _meshColor2X_Default; _isVisible = _isVisible_Default; } if (!_isVisible) { _meshColor2X.a = 0.0f; } if (_parentTransform != null) { //변경 전 //_calculateTmpMatrix.SRMultiply(_parentTransform.CalculatedTmpMatrix, true); //_matrix_TF_Cal_ToWorld = _calculateTmpMatrix.MtrxToSpace; //변경 후 _matrix_TF_ParentWorld.SetMatrix(_parentTransform._matrix_TFResult_World); _matrix_TF_ParentWorld_NonModified.SetMatrix(_parentTransform._matrix_TFResult_WorldWithoutMod); //색상은 2X 방식의 Add _meshColor2X.r = Mathf.Clamp01(((float)(_meshColor2X.r) - 0.5f) + ((float)(_parentTransform._meshColor2X.r) - 0.5f) + 0.5f); _meshColor2X.g = Mathf.Clamp01(((float)(_meshColor2X.g) - 0.5f) + ((float)(_parentTransform._meshColor2X.g) - 0.5f) + 0.5f); _meshColor2X.b = Mathf.Clamp01(((float)(_meshColor2X.b) - 0.5f) + ((float)(_parentTransform._meshColor2X.b) - 0.5f) + 0.5f); _meshColor2X.a *= _parentTransform._meshColor2X.a; } if (_meshColor2X.a < VISIBLE_ALPHA //|| !CalculatedStack.IsMeshVisible ) { _isVisible = false; _meshColor2X.a = 0.0f; } //MakeTransformMatrix(); < 이 함수 부분 //World Matrix를 만든다. _matrix_TFResult_World.RMultiply(_matrix_TF_ToParent); //변경 : ToParent -> LocalModified -> ParentWorld 순으로 바꾼다. _matrix_TFResult_World.RMultiply(_matrix_TF_LocalModified); //<<[R] //_matrix_TFResult_World.RMultiply(_matrix_TF_ToParent);//<<[R] _matrix_TFResult_World.RMultiply(_matrix_TF_ParentWorld); //<<[R] //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ToParent, true);//ToParent는 넣지 않는다. //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ParentWorld, true);//<<[SR] _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ToParent); //<<[R] _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ParentWorld_NonModified); //<<[R] #if UNITY_EDITOR Profiler.EndSample(); #endif //[MeshUpdate]는 Post Update로 전달 //3. 자식 호출 //자식 객체도 업데이트를 한다. if (_childTransforms != null) { for (int i = 0; i < _childTransforms.Length; i++) { _childTransforms[i].UpdateCalculate_Pre(); } } }
public void ReadyToUpdate() { //1. Child Mesh와 기본 Reday if (_childMesh != null) { _childMesh.ReadyToUpdate(); } //2. Calculate Stack Ready if (_calculatedStack != null) { _calculatedStack.ReadyToCalculate(); } //3. 몇가지 변수 초기화 _meshColor2X = new Color(0.5f, 0.5f, 0.5f, 1.0f); _isVisible = true; //Editor에서는 기본 matrix가 들어가지만, 여기서는 아예 Transform(Mono)에 들어가기 때문에 Identity가 된다. //_matrix_TF_Cal_ToWorld = apMatrix3x3.identity; //_calculateTmpMatrix.SetIdentity(); //변경 //[Parent World x To Parent x Local TF] 조합으로 변경 if (_matrix_TF_ParentWorld == null) { _matrix_TF_ParentWorld = new apMatrix(); } if (_matrix_TF_ParentWorld_NonModified == null) { _matrix_TF_ParentWorld_NonModified = new apMatrix(); } if (_matrix_TF_ToParent == null) { _matrix_TF_ToParent = new apMatrix(); } if (_matrix_TF_LocalModified == null) { _matrix_TF_LocalModified = new apMatrix(); } if (_matrix_TFResult_World == null) { _matrix_TFResult_World = new apMatrix(); } if (_matrix_TFResult_WorldWithoutMod == null) { _matrix_TFResult_WorldWithoutMod = new apMatrix(); } _matrix_TF_ParentWorld.SetIdentity(); _matrix_TF_ParentWorld_NonModified.SetIdentity(); //_matrix_TF_ToParent.SetIdentity(); _matrix_TF_LocalModified.SetIdentity(); //Editor에서는 기본 matrix가 들어가지만, 여기서는 아예 Transform(Mono)에 들어가기 때문에 Identity가 된다. _matrix_TF_ToParent.SetMatrix(_defaultMatrix); _matrix_TFResult_World.SetIdentity(); _matrix_TFResult_WorldWithoutMod.SetIdentity(); //3. 자식 호출 //자식 객체도 업데이트를 한다. if (_childTransforms != null) { for (int i = 0; i < _childTransforms.Length; i++) { _childTransforms[i].ReadyToUpdate(); } } }
///// <summary> ///// 초기화/3) Parent Matrix를 넣는다. 바뀐게 없다면 더 호출하지 않아도 된다. ///// (에디터에서 메뉴에서 선택시, 처음 초기화시 호출해야함) ///// </summary> ///// <param name="parentMatrix"></param> //public void SetParentMatrix(apMatrix parentMatrix) //{ // _parentMatrix = parentMatrix; //} /// <summary> /// 4) World Matrix를 만든다. /// 이 함수는 Parent의 MeshGroupTransform이 연산된 후 -> Vertex가 연산되기 전에 호출되어야 한다. /// </summary> public void MakeWorldMatrix(bool isRecursive) { _localMatrix.SetIdentity(); _localMatrix._pos = _deltaPos; _localMatrix._angleDeg = _deltaAngle; _localMatrix._scale.x = _deltaScale.x; _localMatrix._scale.y = _deltaScale.y; _localMatrix.MakeMatrix(); //World Matrix = ParentMatrix x LocalMatrix //Root인 경우에는 MeshGroup의 Matrix를 이용하자 //_invWorldMatrix_NonModified.SetIdentity(); if (_parentBone == null) { _worldMatrix.SetMatrix(_defaultMatrix); _worldMatrix_NonModified.SetMatrix(_defaultMatrix); if (_isRigTestPosing) { _worldMatrix.Add(_rigTestMatrix); //Rig Test 추가 } _worldMatrix.Add(_localMatrix); if (_renderUnit != null) { //Non Modified도 동일하게 적용 //렌더유닛의 WorldMatrix를 넣어주자 //_worldMatrix.RMultiply(_renderUnit._meshGroup._rootMeshGroupTransform._matrix); _worldMatrix.RMultiply(_renderUnit.WorldMatrixWrap); _worldMatrix_NonModified.RMultiply(_renderUnit.WorldMatrixWrapWithoutModified); ////Inverse도 만들어주자 ////Inverse의 시작점부터 //if (_renderUnit._meshTransform != null)//TODO : 이거 고칠것 (MeshGroup Transform 포함하게) //{ // _invWorldMatrix.SetMatrix(_renderUnit._meshTransform._invMatrix_TFResult_World); // _invWorldMatrix_NonModified.SetMatrix(_renderUnit._meshTransform._invMatrix_TFResult_WorldWithoutMod); // //_invWorldMatrix_NonModified.SetIdentity(); // //_invWorldMatrix_NonModified.RInverse(_renderUnit._meshTransform._invMatrix_TFResult_WorldWithoutMod); //} } //else //{ // _invWorldMatrix.SetIdentity(); // _invWorldMatrix_NonModified.SetIdentity(); //} } else { _worldMatrix.SetMatrix(_defaultMatrix); _worldMatrix_NonModified.SetMatrix(_defaultMatrix); if (_isRigTestPosing) { _worldMatrix.Add(_rigTestMatrix); //Rig Test 추가 } _worldMatrix.Add(_localMatrix); _worldMatrix.RMultiply(_parentBone._worldMatrix); //주의, Parent의 NonModifiedMatrix를 적용할 것 _worldMatrix_NonModified.RMultiply(_parentBone._worldMatrix_NonModified); //Inverse를 적용하자 //_invWorldMatrix.SetMatrix(_parentBone._invWorldMatrix); //_invWorldMatrix_NonModified.SetMatrix(_parentBone._invWorldMatrix_NonModified); //_invWorldMatrix_NonModified.SetIdentity(); //_invWorldMatrix_NonModified.RInverse(_parentBone._invWorldMatrix_NonModified); } ////Inverse 이어서 작업 //_invWorldMatrix.RInverse(_localMatrix); //if(_isRigTestPosing) //{ // _invWorldMatrix.Subtract(_rigTestMatrix); //} //_invWorldMatrix.Subtract(_defaultMatrix); //_invWorldMatrix_NonModified.RInverse(_defaultMatrix); ////_invWorldMatrix_NonModified.Subtract(_defaultMatrix); //if (string.Equals(_name, "Bone 2 Debug")) //{ // //디버그를 해보자 // Debug.Log("------- Bone Matrix [" + _name + "] ------- (Editor)"); // Debug.Log("Default Matrix [" + _defaultMatrix.ToString() + "]"); // Debug.Log("Local Matrix [" + _localMatrix.ToString() + "]"); // if (_parentBone != null) // { // Debug.Log("Parent(" + _parentBone._name + ")"); // Debug.Log(">> World Matrix [" + _parentBone._worldMatrix.ToString() + "]"); // Debug.Log(">> World Matrix No Mod [" + _parentBone._worldMatrix_NonModified.ToString() + "]"); // } // Debug.Log("World Matrix [" + _worldMatrix.ToString() + "]"); // Debug.Log("World Matrix No Mod [" + _worldMatrix_NonModified.ToString() + "]"); // Debug.Log("-----------------------------------------"); //} //Child도 호출해준다. if (isRecursive) { for (int i = 0; i < _childBones.Count; i++) { _childBones[i].MakeWorldMatrix(true); } } }
/// <summary> /// Calculate Result Statck의 업데이트 부분 /// Pre-Update로서 VertWorld와 Rigging이 제외된다. /// </summary> public void Calculate_Pre() { //bool isFirstDebug = true; _cal_prevWeight = 0.0f; _cal_curWeight = 0.0f; _cal_resultParam = null; _cal_posVerts = null; //Debug.Log("Is Any Vert Local : " + _isAnyVertLocal + " [" + _resultParams_VertLocal.Count +"]"); // 1. Local Morph if (_isAnyVertLocal) { #if UNITY_EDITOR Profiler.BeginSample("Calcuate Result Stack - 1. Vert Local"); #endif _cal_prevWeight = 0.0f; _cal_curWeight = 0.0f; _cal_resultParam = null; _cal_posVerts = null; _iCalculatedParam = 0; //<<추가 : 첫 모디파이어는 무조건 Interpolation으로 만들자 for (int iParam = 0; iParam < _resultParams_VertLocal.Count; iParam++) { _cal_resultParam = _resultParams_VertLocal[iParam]; _cal_curWeight = _cal_resultParam.ModifierWeight; if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f) { continue; } _cal_posVerts = _cal_resultParam._result_Positions; if (_result_VertLocal == null) { Debug.LogError("Result Vert Local is Null"); } if (_cal_posVerts == null) { Debug.LogError("Cal Pos Vert is Null"); } if (_cal_posVerts.Count != _result_VertLocal.Length) { //결과가 잘못 들어왔다 갱신 필요 Debug.LogError("Wrong Vert Local Result (Cal : " + _cal_posVerts.Count + " / Verts : " + _result_VertLocal.Length + ")"); continue; } // Blend 방식에 맞게 Pos를 만들자 if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0) { for (int i = 0; i < _cal_posVerts.Count; i++) { _result_VertLocal[i] = BlendPosition_ITP(_result_VertLocal[i], _cal_posVerts[i], _cal_curWeight); //if (isFirstDebug) //{ // if (_result_VertLocal[i].sqrMagnitude > 0.0f) // { // Debug.Log("Valid Result Local : " + _result_VertLocal[i]); // isFirstDebug = false; // } //} } _cal_prevWeight += _cal_curWeight; } else { for (int i = 0; i < _cal_posVerts.Count; i++) { _result_VertLocal[i] = BlendPosition_Add(_result_VertLocal[i], _cal_posVerts[i], _cal_curWeight); } } _iCalculatedParam++; } #if UNITY_EDITOR Profiler.EndSample(); #endif } // 2. Mesh / MeshGroup Transformation if (_isAnyTransformation) { #if UNITY_EDITOR Profiler.BeginSample("Calcuate Result Stack - 2. MeshGroup Transformation"); #endif _cal_prevWeight = 0.0f; _cal_curWeight = 0.0f; _cal_resultParam = null; _iCalculatedParam = 0; //Debug.Log("Update TF - OPT"); for (int iParam = 0; iParam < _resultParams_Transform.Count; iParam++) { _cal_resultParam = _resultParams_Transform[iParam]; _cal_curWeight = _cal_resultParam.ModifierWeight; if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f) { continue; } // Blend 방식에 맞게 Matrix를 만들자 하자 if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0) { //Debug.Log("Cal TF [ITP] : " + _cal_resultParam._result_Matrix.Pos3 + " (Weight : " + _cal_curWeight + ")"); BlendMatrix_ITP(_result_MeshTransform, _cal_resultParam._result_Matrix, _cal_curWeight); //if (_cal_resultParam._result_Matrix.Scale2.magnitude < 0.5f || _cal_curWeight < 0.5f) //{ // Debug.Log("Cal TF [ITP] : " + _cal_resultParam._result_Matrix.Scale2 + " > " + _result_MeshTransform.Scale2 + " (Weight : " + _cal_curWeight + ")"); //} _cal_prevWeight += _cal_curWeight; } else { BlendMatrix_Add(_result_MeshTransform, _cal_resultParam._result_Matrix, _cal_curWeight); } _iCalculatedParam++; } _result_MeshTransform.MakeMatrix(); if (_result_MeshTransform._scale.magnitude < 0.5f) { Debug.Log("Cal TF [ITP] : " + _result_MeshTransform._scale + " (Total Weight : " + _cal_prevWeight + ")"); } #if UNITY_EDITOR Profiler.EndSample(); #endif } // 3. Mesh Color if (_isAnyMeshColor) { #if UNITY_EDITOR Profiler.BeginSample("Calcuate Result Stack - 3. Mesh Color"); #endif _cal_prevWeight = 0.0f; _cal_curWeight = 0.0f; _cal_resultParam = null; _iCalculatedParam = 0; _result_IsVisible = false; _nMeshColorCalculated = 0; _result_CalculatedColor = false; for (int iParam = 0; iParam < _resultParams_MeshColor.Count; iParam++) { _cal_resultParam = _resultParams_MeshColor[iParam]; _cal_curWeight = Mathf.Clamp01(_cal_resultParam.ModifierWeight); if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f || !_cal_resultParam.IsColorValueEnabled || !_cal_resultParam._isColorCalculated //<<추가 : Color로 등록했지만 아예 계산이 안되었을 수도 있다. ) { continue; } //<<TODO // Blend 방식에 맞게 Matrix를 만들자 하자 if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0) { //_result_Color = BlendColor_ITP(_result_Color, _cal_resultParam._result_Color, _cal_prevWeight, _cal_curWeight); _result_Color = apUtil.BlendColor_ITP(_result_Color, _cal_resultParam._result_Color, _cal_curWeight); _cal_prevWeight += _cal_curWeight; } else { _result_Color = apUtil.BlendColor_Add(_result_Color, _cal_resultParam._result_Color, _cal_curWeight); } _result_IsVisible |= _cal_resultParam._result_IsVisible; _nMeshColorCalculated++; _result_CalculatedColor = true; //<<"계산된 MeshColor" Result가 있음을 알린다. _iCalculatedParam++; } if (_nMeshColorCalculated == 0) { _result_IsVisible = true; } #if UNITY_EDITOR Profiler.EndSample(); #endif } else { _result_IsVisible = true; } //AnyBoneTransform if (_isAnyBoneTransform) { _cal_prevWeight = 0.0f; _cal_curWeight = 0.0f; _cal_resultParam = null; for (int iBonePair = 0; iBonePair < _resultParams_BoneTransform.Count; iBonePair++) { OptBoneAndModParamPair boneModPair = _resultParams_BoneTransform[iBonePair]; apOptBone targetBone = boneModPair._keyBone; List <OptModifierAndResultParamListPair> modParamPairs = boneModPair._modParamPairs; if (targetBone == null || modParamPairs.Count == 0) { continue; } _iCalculatedParam = 0; _result_BoneTransform.SetIdentity(); apMatrix lastMatrix = new apMatrix(); for (int iModParamPair = 0; iModParamPair < modParamPairs.Count; iModParamPair++) { OptModifierAndResultParamListPair modParamPair = modParamPairs[iModParamPair]; for (int iParam = 0; iParam < modParamPair._resultParams.Count; iParam++) { _cal_resultParam = modParamPair._resultParams[iParam]; _cal_curWeight = _cal_resultParam.ModifierWeight; if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f) { continue; } // Blend 방식에 맞게 Matrix를 만들자 하자 if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0) { BlendMatrix_ITP(_result_BoneTransform, _cal_resultParam._result_Matrix, _cal_curWeight); _cal_prevWeight += _cal_curWeight; } else { BlendMatrix_Add(_result_BoneTransform, _cal_resultParam._result_Matrix, _cal_curWeight); } lastMatrix.SetMatrix(_cal_resultParam._result_Matrix); _iCalculatedParam++; } } //참조된 본에 직접 값을 넣어주자 targetBone.UpdateModifiedValue(_result_BoneTransform._pos, _result_BoneTransform._angleDeg, _result_BoneTransform._scale); if (_result_BoneTransform._scale.magnitude < 0.3f && targetBone.name.Contains("Pelvis")) { Debug.LogError("본 사이즈가 너무 작다 : " + targetBone.name + " / Num CalParam : " + _iCalculatedParam + " / 마지막 Weight : " + _cal_curWeight + " / 마지막 Matrix : " + lastMatrix.ToString()); } } } }
//Link 함수의 내용은 Bake 시에 진행해야한다. /// <summary> /// [Please do not use it] /// </summary> /// <param name="bone"></param> public void Bake(apBone bone) { _name = bone._name; _uniqueID = bone._uniqueID; _meshGroupID = bone._meshGroupID; _defaultMatrix.SetMatrix(bone._defaultMatrix); _deltaPos = Vector2.zero; _deltaAngle = 0.0f; _deltaScale = Vector2.one; _localMatrix.SetIdentity(); _worldMatrix.SetIdentity(); _worldMatrix_NonModified.SetIdentity(); _vertWorld2BoneModWorldMatrix.SetIdentity(); _color = bone._color; _shapeWidth = bone._shapeWidth; _shapeLength = bone._shapeLength; _shapeTaper = bone._shapeTaper; _optionLocalMove = bone._optionLocalMove; _optionIK = bone._optionIK; _isIKTail = bone._isIKTail; _IKTargetBoneID = bone._IKTargetBoneID; _IKTargetBone = null; //<<나중에 링크 _IKNextChainedBoneID = bone._IKNextChainedBoneID; _IKNextChainedBone = null; //<<나중에 링크 _IKHeaderBoneID = bone._IKHeaderBoneID; _IKHeaderBone = null; //<<나중에 링크 _isIKAngleRange = bone._isIKAngleRange; //이게 기존 코드 //_IKAngleRange_Lower = bone._IKAngleRange_Lower; //_IKAngleRange_Upper = bone._IKAngleRange_Upper; //_IKAnglePreferred = bone._IKAnglePreferred; //이게 변경된 IK 코드 _IKAngleRange_Lower = bone._defaultMatrix._angleDeg + bone._IKAngleRange_Lower; _IKAngleRange_Upper = bone._defaultMatrix._angleDeg + bone._IKAngleRange_Upper; _IKAnglePreferred = bone._defaultMatrix._angleDeg + bone._IKAnglePreferred; _isIKCalculated = false; _IKRequestAngleResult = 0.0f; _IKRequestWeight = 0.0f; _socketTransform = null; _transformLocalMatrix.SetIdentity(); _childBones = null; _isIKChainInit = false; }