//개선된 버전 19.5.23 public void Link(apOptModifiedMesh_Physics modMeshPhysics, apOptModifiedMeshSet modMeshSet, apOptTransform optTransform, apOptRenderVertex vertex) { //>>19.5.23 : 삭제 (불필요) //_modifiedMesh = modifiedMesh; //_mesh = mesh; _vertex = vertex; _optTransform = optTransform; if (_linkedVertices == null) { _linkedVertices = new List <LinkedVertex>(); } apOptMesh mesh = modMeshSet._targetMesh; //이미 Bake 되었으므로 바로 Link하면 된다. for (int i = 0; i < _linkedVertices.Count; i++) { LinkedVertex linkedVert = _linkedVertices[i]; apOptRenderVertex renderVert = mesh.RenderVertices[linkedVert._vertIndex]; apOptModifiedPhysicsVertex linkVert = modMeshSet.SubModMesh_Physics._vertWeights[linkedVert._vertIndex]; linkedVert.Link(renderVert, linkVert); } DampPhysicVertex(); }
/// <summary> /// Linked Vertex의 Dist, Weight을 갱신하자 /// LinkedVertex는 Link에서 미리 만들자 /// </summary> public void RefreshLinkedVertex() { if (_parentModMesh._transform_Mesh == null || _parentModMesh._transform_Mesh._mesh == null || _parentModVertWeight._vertex == null) { return; } float totalDist = 0.0f; for (int i = 0; i < _linkedVertices.Count; i++) { LinkedVertex linkVert = _linkedVertices[i]; linkVert.SetDistance(_parentModVertWeight._vertex._pos - linkVert._vertex._pos); totalDist += linkVert._distLocal; } if (totalDist > 0.0f) { if (_linkedVertices.Count > 1) { float totalWeight = totalDist * (_linkedVertices.Count - 1); for (int i = 0; i < _linkedVertices.Count; i++) { LinkedVertex linkVert = _linkedVertices[i]; linkVert.SetWeight((totalDist - linkVert._distLocal) / totalWeight); //Normalized된 Weight를 넣자 } } else if (_linkedVertices.Count == 0) { _linkedVertices[0].SetWeight(1.0f); } } //Vector2 localPos = _parentModVertWeight._vertex._pos; ////public Vector2 _deltaPosLocal = Vector2.zero; ////public float _distLocal = 0.0f; ////public float _distWeight = 0.0f; ////Local 기반 거리를 체크하고, ////가까울 수록 weight를 증가시킨다. ////다른 것들과 유효한지 체크한다. ////굳이 유효한 것만 체크하는 건 아니다. ////장력은 Enabled = false 인 것과도 행해지기 때문 ////IDW가 아니라 ////Linear Reverse Interpolation의 Normalize로 한다. //LinkedVertex linkVert = null; //float totalDist = 0.0f; //for (int i = 0; i < _linkedVertices.Count; i++) //{ // linkVert = _linkedVertices[i]; // Vector2 targetPos = linkVert._vertex._pos; // linkVert._deltaPosLocalLinkToTarget = targetPos - localPos; // linkVert._distLocal = Vector2.Distance(targetPos, localPos); // linkVert._distWeight = 0.0f; // totalDist += linkVert._distLocal; //} //float totalWeight = 0.0f; //for (int i = 0; i < _linkedVertices.Count; i++) //{ // linkVert = _linkedVertices[i]; // linkVert._distWeight = totalDist - linkVert._distLocal;//가까울 수록 Weight가 크다 // totalWeight += linkVert._distWeight; //} //if (totalWeight > 0.0f) //{ // for (int i = 0; i < _linkedVertices.Count; i++) // { // linkVert = _linkedVertices[i]; // linkVert._distWeight /= totalWeight; // } //} }
/// <summary> /// Linked Vertex의 객체를 Link한다. /// </summary> /// <param name="parentModMesh"></param> public void Link(apModifiedMesh parentModMesh, apModifiedVertexWeight parentModVertWeight) { _parentModMesh = parentModMesh; _parentModVertWeight = parentModVertWeight; if (_linkedVertices == null) { _linkedVertices = new List <LinkedVertex>(); } if (parentModMesh._transform_Mesh == null || parentModMesh._transform_Mesh._mesh == null) { Debug.LogError("Physics Param Link Error : MeshTransform is Null of Mesh is Null"); return; } //???? //이게 왜 Link에 있지?? //이거 많이 느림 //데이터 저장 후 ID를 통해서 바로 Link해야하는데 매번 조회 후 생성+연결하려고 함. //이 부분을 고쳐서 Physic.LinkedVertex를 미리 생성하고 여기서는 바로 연결해야한다. 로딩 느릴수밖에 없네.. //TODO //...대체 방법이 없는데요.. apMesh mesh = parentModMesh._transform_Mesh._mesh; //int maxVertLevel = 3; int maxVertLevel = 1; //연결된 apVertex를 받아오자 (최대 3레벨) //수정 > 1레벨로도 충분할 듯 List <apMesh.LinkedVertexResult> linkedVerticesOnMesh = mesh.GetLinkedVertex(_parentModVertWeight._vertex, maxVertLevel); //두개의 리스트를 비교하여 //- 같으면 단순 Link //- 없으면 추가해서 Link //- 연결되지 않았으면 제외 //+Contraint 체크를 위해서, 1-Level 을 따로 분류 (또는 Level 값을 넣자) //1. 추가할 것을 체크하자 apMesh.LinkedVertexResult srcVert = null; apModifiedVertexWeight modVertWeight = null; for (int iSrcVert = 0; iSrcVert < linkedVerticesOnMesh.Count; iSrcVert++) { srcVert = linkedVerticesOnMesh[iSrcVert]; modVertWeight = _parentModMesh.GetVertexWeight(srcVert._vertex); LinkedVertex linkedVert = _linkedVertices.Find(delegate(LinkedVertex a) { return(a._vertUniqueID == srcVert._vertex._uniqueID); }); if (linkedVert == null) { //새로 추가해야하는 Linked Vert LinkedVertex newLinkedVert = new LinkedVertex(srcVert._vertex, srcVert._level); newLinkedVert.Link(srcVert._vertex, modVertWeight); _linkedVertices.Add(newLinkedVert); } else { //이미 추가되었으니 Link만 하자 linkedVert.Link(srcVert._vertex, modVertWeight); } } //2. 이제 제거할 것을 체크하자 //연결 안된건 지우자 _linkedVertices.RemoveAll(delegate(LinkedVertex a) { if (a._vertex == null || a._modVertWeight == null) { return(true); } if (!linkedVerticesOnMesh.Exists(delegate(apMesh.LinkedVertexResult b) { return(b._vertex == a._vertex); })) { //연결된게 아니다. 찾을 수 없다. return(true); } return(false); }); //전체 길이를 체크하여 역 Weight를 걸자 RefreshLinkedVertex(); }