private void SerializeAndSearchAllPoints(ADBRuntimePoint point, ref List <ADBRuntimePoint> allPointList, out int maxPointDepth)//OYM:在这里递归搜索 { if (point == null) { maxPointDepth = 0; return; } if (point.childNode == null) {//OYM:没有子节点 if (point.depth == 0 || aDBSetting.isComputeVirtual) { //OYM:如果只有一个节点,而且还是一个fix点 addVirtualPointList.Add(point); } else { //OYM:不是的话就当做最后一个节点处理 point.pointRead.childFirstIndex = -1; point.pointRead.childLastIndex = -1; } point.pointDepthRateMaxPointDepth = 1; maxPointDepth = point.depth; return; } else //OYM:有子节点的情况 { point.pointRead.childFirstIndex = allPointList.Count; //OYM:记录第一个子节点的位置 point.pointRead.childLastIndex = point.pointRead.childFirstIndex + point.childNode.Count; //OYM:记录最后一个子节点的位置 maxPointDepth = point.depth; //OYM:广度遍历 for (int i = 0; i < point.childNode.Count; i++) { var childPoint = point.childNode[i]; childPoint.pointRead.parent = point.index; childPoint.pointRead.boneAxis = point.trans.InverseTransformPoint(childPoint.trans.position).normalized; childPoint.pointRead.localRotation = childPoint.trans.localRotation; childPoint.index = allPointList.Count; childPoint.pointRead.fixedIndex = childPoint.isFixed ? childPoint.index : point.pointRead.fixedIndex; allPointList.Add(point.childNode[i]); } for (int i = 0; i < point.childNode.Count; i++) { int maxDeep = point.depth; SerializeAndSearchAllPoints(point.childNode[i], ref allPointList, out maxDeep); if (maxDeep > maxPointDepth) { maxPointDepth = maxDeep; point.pointDepthRateMaxPointDepth = point.depth / (float)maxDeep; } } } }
private void SerializeVirtuaPoint(ref List <ADBRuntimePoint> PointList) //OYM:generate virtual point and a ConstraintStructuralVertical between then. { for (int i = 0; i < PointList.Count; i++) //OYM:在这里生成一个不存在的点,用于处理只有一个点控制骨骼的情况(比如前额头发),这里给它了一个oldposition加上一个Vector3.down { if (PointList[i].childNode == null && !PointList[i].isVirtual) { var virtualPoint = new ADBRuntimePoint(PointList[i].trans, PointList[i].depth + 1, PointList[i].keyWord, true); PointList[i].childNode = new List <ADBRuntimePoint>() { virtualPoint }; PointList[i].pointRead.childFirstIndex = allNodeList.Count; PointList[i].pointRead.childLastIndex = allNodeList.Count + 1; virtualPoint.index = allNodeList.Count; virtualPoint.pointRead.fixedIndex = PointList[i].pointRead.fixedIndex; virtualPoint.pointRead.childFirstIndex = virtualPoint.pointRead.childLastIndex = -1; virtualPoint.pointRead.parent = PointList[i].index; virtualPoint.pointDepthRateMaxPointDepth = aDBSetting.virtualPointRate; virtualPoint.pointRead.boneAxis = Vector3.down * 0.1f; virtualPoint.pointRead.localRotation = Quaternion.identity; virtualPoint.pointRead.initialPosition = Vector3.zero; allNodeList.Add(virtualPoint); } } constraintsVirtual = new List <ADBConstraintRead>(); for (int i = 0; i < PointList.Count; ++i) { CreateConstraintStructuralVertical(PointList[i], ref constraintsVirtual, aDBSetting.structuralShrinkVertical, aDBSetting.structuralStretchVertical); } for (int i = 0; i < constraintsVirtual.Count; i++) { constraintsVirtual[i].constraintRead.isCollider = false; constraintsVirtual[i].constraintRead.type = ConstraintType.Virtual; } }
public ADBConstraintReadAndPointControll(ADBRuntimePoint rootNode, string keyWord, ADBSetting setting) { this.rootNode = rootNode;//OYM:rootpoint指所有fix骨骼的同一个父节点,他会独立出来,而不是参与到计算当中 rootNode.index = -1; this.keyWord = keyWord; fixedNodeList = new List <ADBRuntimePoint>(); allNodeList = new List <ADBRuntimePoint>(); maxNodeDepth = 1; aDBSetting = setting; }
//OYM:new一个出来 private ADBConstraintReadAndPointControll(Transform rootTransform, string keyWord, ADBSetting setting) { rootNode = new ADBRuntimePoint(rootTransform, -1);//OYM:rootpoint指所有fix骨骼的同一个父节点,他会独立出来,而不是参与到计算当中 rootNode.index = -1; this.keyWord = keyWord; fixedNodeList = new List <ADBRuntimePoint>(); allNodeList = new List <ADBRuntimePoint>(); addVirtualPointList = new List <ADBRuntimePoint>(); maxNodeDepth = 1; aDBSetting = setting; }
private void CreationConstraintHorizontal(ADBRuntimePoint PointA, ADBRuntimePoint PointB, ref List <ADBConstraintRead> ConstraintList, float shrink, float stretch)//OYM:我建议你不要去看他,你只要相信他能够正常工作就好了 { if ((PointA == null) || (PointB == null)) { return; //OYM:判空 } if (PointA == PointB) { return; //OYM:这里是如果只有一条子列的话防止赋值自身 } var childPointAList = PointA.childNode; var childPointBList = PointB.childNode;//OYM:获取子节点上的点 if ((childPointAList != null) && (childPointBList != null)) { if (childPointAList[0].isVirtual || childPointBList[0].isVirtual) { return; //OYM:虚点不参与其中 } if (childPointAList.Count >= 2) //OYM:存在多个子节点 { sortByDistance(childPointBList[0], ref childPointAList, false); sortByDistance(childPointAList[childPointAList.Count - 1], ref childPointBList, true);//OYM:好吧就这么写吧以后谁倒霉谁来改 for (int i = 0; i < childPointAList.Count - 1; i++) { ConstraintList.Add(new ADBConstraintRead(ConstraintType.Structural_Horizontal, childPointAList[i], childPointAList[i + 1], shrink, stretch, aDBSetting.isComputeBendingHorizontal)); CreationConstraintHorizontal(childPointAList[i], childPointAList[i + 1], ref ConstraintList, shrink, stretch);//OYM:递归 } } ConstraintList.Add(new ADBConstraintRead(ConstraintType.Structural_Horizontal, childPointAList[childPointAList.Count - 1], childPointBList[0], shrink, stretch, aDBSetting.isComputeBendingHorizontal)); CreationConstraintHorizontal(childPointAList[childPointAList.Count - 1], childPointBList[0], ref ConstraintList, shrink, stretch); //OYM:递归 } else if ((childPointAList != null) && (childPointBList == null)) //OYM:为了防止互相连接,只允许向序号增大的方向进行连接 { if (childPointAList[0].isVirtual) { return; //OYM:虚点不参与其中 } sortByDistance(PointB, ref childPointAList, false); if (childPointAList.Count >= 2)//OYM:存在多个子节点 { for (int i = 0; i < childPointAList.Count - 1; i++) { ConstraintList.Add(new ADBConstraintRead(ConstraintType.Structural_Horizontal, childPointAList[i], childPointAList[i + 1], shrink, stretch, aDBSetting.isComputeBendingHorizontal)); CreationConstraintHorizontal(childPointAList[i], childPointAList[i + 1], ref ConstraintList, shrink, stretch);//OYM:递归 } } ConstraintList.Add(new ADBConstraintRead(ConstraintType.Structural_Horizontal, childPointAList[childPointAList.Count - 1], PointB, shrink, stretch, aDBSetting.isComputeBendingHorizontal)); CreationConstraintHorizontal(childPointAList[childPointAList.Count - 1], PointB, ref ConstraintList, shrink, stretch); } }
public ADBRuntimeConstraint(ConstraintType type, ADBRuntimePoint pointA, ADBRuntimePoint pointB, float shrink, float stretch, bool isCollide) { constraintRead.type = type; this.pointA = pointA; this.pointB = pointB; // constraintRead.radius = 0.5f*(pointA.pointRead.radius+ pointB.pointRead.radius);要用这个属性自己改,反正用起来太奇怪了=w= constraintRead.indexA = pointA.index; constraintRead.indexB = pointB.index; constraintRead.shrink = shrink; constraintRead.stretch = stretch; constraintRead.isCollider = isCollide; this.direction = pointA.trans.position - pointB.trans.position; constraintRead.length = (this.direction).magnitude; }
private static void sortByDistance(ADBRuntimePoint target, ref List <ADBRuntimePoint> List, bool isInverse) { //OYM:这里请允许我花点时间啰嗦一下,如果不颠倒,则距离短的在后,如果颠倒的话,则距离短的在前 if (List.Count < 2 || target == null) { return; } int fore = isInverse ? 1 : -1; List.Sort((point1, point2) => { return((Vector3.Distance(point1.trans.position, target.trans.position) > Vector3.Distance(point2.trans.position, target.trans.position)) ? -fore : fore); }); }
private void CreateConstraintStructuralVertical(ADBRuntimePoint Point, ref List <ADBConstraintRead> ConstraintList, float shrink, float stretch) { if (Point == null || Point.childNode == null) { return; } for (int i = 0; i < Point.childNode.Count; ++i) { var constraint = new ADBConstraintRead(ConstraintType.Structural_Vertical, Point, Point.childNode[i], shrink, stretch, aDBSetting.isCollideStructuralVertical); ConstraintList.Add(constraint); CreateConstraintStructuralVertical(Point.childNode[i], ref ConstraintList, shrink, stretch); } }
public ADBConstraintRead(ConstraintType type, ADBRuntimePoint pointA, ADBRuntimePoint pointB, float shrink, float stretch, bool isCollide, float freeAngle = 0, Vector3?normal = null) //OYM:说实话这个v3我一点都不想携程这样,但是不这么写直接赋值vector3.zero又报错 { constraintRead.type = type; this.pointA = pointA; this.pointB = pointB; constraintRead.indexA = pointA.index; constraintRead.indexB = pointB.index; constraintRead.shrink = shrink; constraintRead.stretch = stretch; CheckLength(); constraintRead.rotationFreeAngle = freeAngle; constraintRead.rotationConstraintNormal = freeAngle == 0?Vector3.zero:(Vector3)normal; constraintRead.isCollider = (type == ConstraintType.Structural_Vertical || type == ConstraintType.Structural_Horizontal || type == ConstraintType.Shear); }
private void CreationConstraintCircumference(ADBRuntimePoint fixedPoint, ref List <ADBConstraintRead> ConstraintList, float shrink, float stretch) { if (fixedPoint == null || fixedPoint.childNode == null) { return; } for (int i = 0; i < fixedPoint.childNode.Count; i++) { if (fixedPoint.childNode[i].isVirtual) { continue; } ConstraintList.Add(new ADBConstraintRead(ConstraintType.Circumference, fixedPoint, fixedPoint.childNode[i], shrink, stretch, false)); CreationConstraintCircumference(fixedPoint, fixedPoint.childNode[i], ref ConstraintList, shrink, stretch);//OYM:递归 } }
private void SerializeVirtuaPoint(ref List <ADBRuntimePoint> PointList) //OYM:generate virtual point and a ConstraintStructuralVertical between then. { for (int i = 0; i < PointList.Count; i++) //OYM:在这里生成一个不存在的点,用于处理只有一个点控制骨骼的情况(比如前额头发),这里给它了一个oldposition加上一个Vector3.down { if (PointList[i].childNode == null && !PointList[i].isVirtual) { var virtualPoint = new ADBRuntimePoint(PointList[i].trans, PointList[i].depth + 1, PointList[i].keyWord, true); PointList[i].childNode = new List <ADBRuntimePoint>() { virtualPoint }; PointList[i].pointRead.childFirstIndex = allNodeList.Count; PointList[i].pointRead.childLastIndex = allNodeList.Count + 1; PointList[i].pointRead.initialLocalRotation = PointList[i].trans.localRotation; PointList[i].pointRead.initialRotation = PointList[i].trans.rotation; virtualPoint.index = allNodeList.Count; virtualPoint.pointRead.fixedIndex = PointList[i].pointRead.fixedIndex; virtualPoint.pointRead.childFirstIndex = virtualPoint.pointRead.childLastIndex = -1; virtualPoint.SetParent(PointList[i]); virtualPoint.pointDepthRateMaxPointDepth = aDBSetting.virtualPointRate; virtualPoint.pointRead.initialLocalPosition = Quaternion.Inverse(PointList[i].trans.rotation) * Vector3.down * 0.1f; virtualPoint.pointRead.initialLocalRotation = virtualPoint.pointRead.initialRotation = Quaternion.identity; var fixedPoint = allNodeList[virtualPoint.pointRead.fixedIndex]; virtualPoint.pointRead.initialPosition = Quaternion.FromToRotation((fixedPoint.trans.rotation * Quaternion.Inverse(fixedPoint.trans.localRotation)) * Vector3.down, aDBSetting.gravity) * Quaternion.Inverse(fixedPoint.trans.rotation) * (virtualPoint.trans.position + virtualPoint.pointRead.initialLocalPosition - fixedPoint.trans.position); //OYM:这里有点啰嗦,是固定位置乘以固定点Y轴的逆向旋转(相当等于回归y初始角度) allNodeList.Add(virtualPoint); } } constraintsVirtual = new List <ADBRuntimeConstraint>(); for (int i = 0; i < PointList.Count; ++i) { CreateConstraintStructuralVertical(PointList[i], ref constraintsVirtual, aDBSetting.structuralShrinkVertical, aDBSetting.structuralStretchVertical); } for (int i = 0; i < constraintsVirtual.Count; i++) { constraintsVirtual[i].constraintRead.isCollider = aDBSetting.isCollideStructuralVertical; constraintsVirtual[i].constraintRead.type = ConstraintType.Virtual; } }
private static void CreationConstraintBendingVertical(ADBRuntimePoint Point, ref List <ADBConstraintRead> ConstraintList, float shrink, float stretch) { if (Point.childNode == null) { return; } foreach (var child in Point.childNode) { if (child.childNode == null) { continue; } foreach (var grandSon in child.childNode) { ConstraintList.Add(new ADBConstraintRead(ConstraintType.Bending_Vertical, Point, grandSon, shrink, stretch, false)); } CreationConstraintBendingVertical(child, ref ConstraintList, shrink, stretch); } }
private void CreationConstraintCircumference(ADBRuntimePoint point, ref List <ADBRuntimeConstraint> ConstraintList, float shrink, float stretch, int deep = 0) { if (point == null || point.childNode == null) { return; } for (int i = 0; i < point.childNode.Count; i++) { if (!point.childNode[i].allowCreateAllConstraint) { continue; //OYM:不允许创建则跳过 } if (deep != 0 && (aDBSetting.isComputeBendingVertical && deep != 1)) //OYM: 第0层通常都有ConstraintStructuralVertical,第一层如果打开ComputeBendingVertical也会重复,所以排除这两种情况. { ConstraintList.Add(new ADBRuntimeConstraint(ConstraintType.Circumference, point, point.childNode[i], shrink, stretch, false)); } CreationConstraintCircumference(point, point.childNode[i], ref ConstraintList, shrink, stretch);//OYM:递归 } }
private void CreationConstraintCircumference(ADBRuntimePoint PointA, ADBRuntimePoint PointB, ref List <ADBConstraintRead> ConstraintList, float shrink, float stretch) { if (PointB == null || PointA == null) { return; //OYM:判空 } var childPointB = PointB.childNode; if ((childPointB != null)) { for (int i = 0; i < childPointB.Count; i++) { var isRepetA = aDBSetting.isComputeStructuralVertical && (childPointB[i].depth == 1); var isRepetB = aDBSetting.isComputeBendingVertical && (childPointB[i].depth == 2); if (!isRepetA && !isRepetB) { ConstraintList.Add(new ADBConstraintRead(ConstraintType.Circumference, PointA, childPointB[i], shrink, stretch, false)); } CreationConstraintCircumference(PointA, childPointB[i], ref ConstraintList, shrink, stretch);//OYM:递归 } } }
private void SerializeAndSearchAllPoints(ADBRuntimePoint point, ref List <ADBRuntimePoint> allPointList, out int maxPointDepth)//OYM:在这里递归搜索 { if (point == null) { maxPointDepth = 0; return; } if (point.childNode == null) {//OYM:没有子节点 if (point.depth == 0 || aDBSetting.isComputeVirtual) { //OYM:如果只有一个节点,而且还是一个fix点 addVirtualPointList.Add(point); } else { //OYM:不是的话就当做最后一个节点处理 point.pointRead.childFirstIndex = -1; point.pointRead.childLastIndex = -1; } point.pointDepthRateMaxPointDepth = 1; maxPointDepth = point.depth; return; } else //OYM:有子节点的情况 { point.pointRead.childFirstIndex = allPointList.Count; //OYM:记录第一个子节点的位置 point.pointRead.childLastIndex = point.pointRead.childFirstIndex + point.childNode.Count; //OYM:记录最后一个子节点的位置 maxPointDepth = point.depth; //OYM:广度遍历 for (int i = 0; i < point.childNode.Count; i++) { var childPoint = point.childNode[i]; childPoint.SetParent(point); childPoint.pointRead.initialLocalPosition = Quaternion.Inverse(point.trans.rotation) * (childPoint.trans.position - point.trans.position); childPoint.pointRead.initialLocalRotation = childPoint.trans.localRotation; childPoint.pointRead.initialRotation = childPoint.trans.rotation; childPoint.index = allPointList.Count; if (childPoint.isFixed) { childPoint.pointRead.fixedIndex = childPoint.index; childPoint.pointRead.initialPosition = Vector3.zero; } else { childPoint.pointRead.fixedIndex = point.pointRead.fixedIndex; var fixedPoint = allPointList[childPoint.pointRead.fixedIndex]; childPoint.pointRead.initialPosition = Quaternion.FromToRotation(Vector3.down, aDBSetting.gravity) * Quaternion.Inverse(fixedPoint.trans.rotation) * (childPoint.trans.position - fixedPoint.trans.position); } //Quaternion.FromToRotation(Vector3.down, aDBSetting.gravity) * (allPointList[childPoint.pointRead.fixedIndex].trans.InverseTransformPoint(childPoint.trans.position) * allPointList[childPoint.pointRead.fixedIndex].trans.lossyScale.x);//OYM:相对于固定点的位置,注意保持大小 allPointList.Add(childPoint); } for (int i = 0; i < point.childNode.Count; i++) { int maxDeep = point.depth; SerializeAndSearchAllPoints(point.childNode[i], ref allPointList, out maxDeep); if (maxDeep > maxPointDepth) { maxPointDepth = maxDeep; point.pointDepthRateMaxPointDepth = point.depth / (float)maxDeep; } } } }
//OYM:deep search the fixed point ,get they childpoint and add it to their point data private static List <ADBRuntimePoint> searchFixedADBRuntimePoint(Transform transform, List <string> generateKeyWordWhiteList, List <string> generateKeyWordBlackList, List <Transform> blackListOfGenerateTransform, int depth) { //OYM:利用深度搜索,能很快找到所有的固定点, //OYM:如果是子节点与父节点匹配,则父节点添加子节点坐标 //OYM: if (transform == null || transform.childCount == 0) { return(null); } //OYM:防空 List <ADBRuntimePoint> ADBRuntimePoint = new List <ADBRuntimePoint>(); for (int i = 0; i < transform.childCount; i++) //OYM:这里就很有意思了 { var childNodeTarns = transform.GetChild(i); //OYM:遍历每一个子节点 var childName = childNodeTarns.name.ToLower(); //OYM:获取他们的名字 ADBRuntimePoint point = null; //OYM:[判断是否属于黑名单 bool isblack = false; for (int j0 = 0; j0 < blackListOfGenerateTransform.Count; j0++) { if (isblack) { break; } isblack = childNodeTarns.Equals(blackListOfGenerateTransform[j0]); } for (int j0 = 0; j0 < generateKeyWordBlackList.Count; j0++) { if (isblack) { break; } isblack = childName.Contains(generateKeyWordBlackList[j0]); } if (isblack) { continue; } foreach (var whiteKey in generateKeyWordWhiteList) { if (whiteKey == null || whiteKey.Length == 0) { continue; } if (childName.Contains(whiteKey)) { point = new ADBRuntimePoint(childNodeTarns, depth, whiteKey); break; } } //OYM:get point child //OYM:注意,这个递归非常有意思,值得好好看看 if (point != null) { List <ADBRuntimePoint> childPoint = searchFixedADBRuntimePoint(point.trans, new List <string> { point.keyWord }, generateKeyWordBlackList, blackListOfGenerateTransform, depth + 1); //OYM:以单一的关键词进行搜索 point.childNode = childPoint; //OYM:注意,这里是设置父节点的子节点,而子节点添加下一层节点搜索到的更深层的子节点 ADBRuntimePoint.Add(point); //OYM:result添加这个父节点,返回给上一级 } //OYM:search next else { List <ADBRuntimePoint> nextNode = searchFixedADBRuntimePoint(childNodeTarns, generateKeyWordWhiteList, generateKeyWordBlackList, blackListOfGenerateTransform, depth);//OYM:这个list会包含所有最顶层的父节点 //OYM:不搜索匹配的子节点,而搜索子节点的所有子节点中是否有匹配的 if (nextNode != null) { ADBRuntimePoint.AddRange(nextNode); } } } ADBRuntimePoint = ADBRuntimePoint.Count == 0 ? null : ADBRuntimePoint; return(ADBRuntimePoint); }
private void CreationConstraintShear(ADBRuntimePoint PointA, ADBRuntimePoint PointB, ref List <ADBConstraintRead> ConstraintList, float shrink, float stretch)//OYM:查找交叉节点 { if ((PointA == null) || (PointB == null)) { return; } if (PointA == PointB) { return; } var childPointAList = PointA.childNode; var childPointBList = PointB.childNode; if (childPointAList != null && childPointBList != null) { if (childPointAList[0].isVirtual || childPointBList[0].isVirtual) { return; //OYM:虚点不参与其中 } sortByDistance(PointB, ref childPointAList, false); sortByDistance(PointA, ref childPointBList, true); if (childPointAList.Count >= 2)//OYM:存在多个子节点 { for (int i = 0; i < childPointAList.Count - 1; i++) { CreationConstraintShear(childPointAList[i], childPointAList[i + 1], ref ConstraintList, shrink, stretch);//OYM:递归 } } if (childPointBList.Count >= 2)//OYM:存在多个子节点 { for (int i = 0; i < childPointBList.Count - 1; i++) { CreationConstraintShear(childPointBList[i], childPointBList[i + 1], ref ConstraintList, shrink, stretch);//OYM:递归 } } ConstraintList.Add(new ADBConstraintRead(ConstraintType.Shear, childPointAList[childPointAList.Count - 1], PointB, shrink, stretch, aDBSetting.isCollideShear)); ConstraintList.Add(new ADBConstraintRead(ConstraintType.Shear, childPointBList[0], PointA, shrink, stretch, aDBSetting.isCollideShear)); CreationConstraintShear(childPointAList[childPointAList.Count - 1], childPointBList[0], ref ConstraintList, shrink, stretch); } else if ((childPointAList != null ^ childPointBList != null) && !aDBSetting.isComputeStructuralHorizontal)//OYM:如果横向创建了,那么斜对角再创建就没有必要了 { var existPoint = childPointAList == null ? PointA : PointB; var existList = childPointAList == null ? childPointBList : childPointAList; if (existPoint.isVirtual || existList[0].isVirtual) { return; //OYM:虚点不参与其中 } sortByDistance(existPoint, ref existList, false); if (existList.Count >= 2)//OYM:存在多个子节点 { for (int i = 0; i < childPointAList.Count - 1; i++) { CreationConstraintHorizontal(existList[i], existList[i + 1], ref ConstraintList, shrink, stretch);//OYM:递归 } } ConstraintList.Add(new ADBConstraintRead(ConstraintType.Shear, existList[existList.Count - 1], existPoint, shrink, stretch, aDBSetting.isCollideShear)); CreationConstraintShear(existList[existList.Count - 1], existPoint, ref ConstraintList, shrink, stretch); } }
//OYM:deep search the fixed point ,get they childpoint and add it to their point data private static List <ADBRuntimePoint> searchFixedADBRuntimePoint(Transform transform, List <string> generateKeyWordWhiteList, List <string> generateKeyWordBlackList, List <Transform> blackListOfGenerateTransform, int depth, ref List <ADBSpringBone> aDBSpringBone) { //OYM:利用深度搜索,能很快找到所有的固定点, //OYM:如果是子节点与父节点匹配,则父节点添加子节点坐标 //OYM: if (transform == null || transform.childCount == 0) { return(null); } //OYM:防空 //==================================SpringBone处理相关=============================== var springBone = transform.GetComponent <ADBSpringBone>(); if (springBone != null && (aDBSpringBone == null || !aDBSpringBone.Contains(springBone))) { if (aDBSpringBone == null) { aDBSpringBone = new List <ADBSpringBone>(); } aDBSpringBone.Add(springBone); if (springBone.fixedPointTransform != null) { springBone.fixedNode = new ADBRuntimePoint(springBone.fixedPointTransform, 0, "");//OYM: 创建fixed节点 } else { springBone.fixedNode = new ADBRuntimePoint(transform, 0, "");//OYM: 创建fixed节点 springBone.fixedPointTransform = transform; } springBone.fixedNode.childNode = searchFixedADBRuntimePoint( springBone.fixedPointTransform, new List <string>() { "" }, springBone.generateKeyWordBlackList, springBone.blackListOfGenerateTransform, 1, ref aDBSpringBone ); List <ADBRuntimePoint> temp = new List <ADBRuntimePoint>() { springBone.fixedNode }; springBone.allTransfromList = new List <Transform>(); for (int j0 = 0; j0 < temp.Count; j0++) { springBone.allTransfromList.Add(temp[j0].trans); if (temp[j0].childNode != null) { temp.AddRange(temp[j0].childNode); } } } //==================================SpringBone处理相关=============================== List <ADBRuntimePoint> ADBRuntimePoint = new List <ADBRuntimePoint>(); for (int i = 0; i < transform.childCount; i++) //OYM:这里就很有意思了 { var childNodeTarns = transform.GetChild(i); //OYM:遍历每一个子节点 var childName = childNodeTarns.name.ToLower(); //OYM:获取他们的名字 ADBRuntimePoint point = null; //OYM:[判断是否属于黑名单 bool isblack = false; for (int j0 = 0; j0 < aDBSpringBone?.Count; j0++)//OYM:是否被Springbone搜索过了 { isblack = aDBSpringBone[j0].fixedPointTransform == childNodeTarns; if (isblack) { break; } } if (isblack) { continue; } for (int j0 = 0; j0 < blackListOfGenerateTransform.Count; j0++)//OYM:是否在节点黑名单 { if (isblack) { break; } isblack = childNodeTarns.Equals(blackListOfGenerateTransform[j0]); } for (int j0 = 0; j0 < generateKeyWordBlackList.Count; j0++)//OYM:是否在名字黑名单 { if (isblack) { break; } isblack = childName.Contains(generateKeyWordBlackList[j0]); } if (!isblack) { foreach (var whiteKey in generateKeyWordWhiteList) { if (whiteKey == null) { continue; } if (childName.Contains(whiteKey)) { point = new ADBRuntimePoint(childNodeTarns, depth, whiteKey);//OYM: 创建fixed节点 break; } } } //OYM:get point child //OYM:注意,这个递归非常有意思,值得好好看看 if (point != null) { List <ADBRuntimePoint> childPoint = searchFixedADBRuntimePoint(point.trans, new List <string> { point.keyWord }, generateKeyWordBlackList, blackListOfGenerateTransform, depth + 1, ref aDBSpringBone); //OYM:以单一的关键词进行搜索 point.childNode = childPoint; //OYM:注意,这里是设置父节点的子节点,而子节点添加下一层节点搜索到的更深层的子节点 ADBRuntimePoint.Add(point); //OYM:result添加这个父节点,返回给上一级 } //OYM:search next else { List <ADBRuntimePoint> nextNode = searchFixedADBRuntimePoint(childNodeTarns, generateKeyWordWhiteList, generateKeyWordBlackList, blackListOfGenerateTransform, depth, ref aDBSpringBone);//OYM:这个list会包含所有最顶层的父节点 //OYM:不搜索匹配的子节点,而搜索子节点的所有子节点中是否有匹配的 if (nextNode != null) { ADBRuntimePoint.AddRange(nextNode); } } } ADBRuntimePoint = ADBRuntimePoint.Count == 0 ? null : ADBRuntimePoint; return(ADBRuntimePoint); }
//OYM:cratePointStruct private void SerializeAndSearchAllPoints(ADBRuntimePoint point, ref List <ADBRuntimePoint> allPointList, out int maxPointDepth)//OYM:在这里递归搜索 { if (point == null) { maxPointDepth = 0; return; } if (point.childNode == null) { //OYM:没有子节点 if (aDBSetting.isComputeVirtual && (!point.trans.name.Contains("virtual"))) //OYM:创建一个延长的节点 { Transform childPointTrans = new GameObject(point.trans.name + " virtual").transform; childPointTrans.position = point.trans.position + ((point.parent?.depth == -1) ? Vector3.down * aDBSetting.virtualPointAxisLength : (point.trans.position - point.parent.trans.position).normalized * aDBSetting.virtualPointAxisLength); childPointTrans.parent = point.trans; ADBRuntimePoint virtualPoint = new ADBRuntimePoint(childPointTrans, point.depth + 1, point.keyWord, aDBSetting.isAllowComputeOtherConstraint); point.childNode = new List <ADBRuntimePoint>() { virtualPoint }; } else { //OYM:不是的话就当做最后一个节点处理 point.pointRead.childFirstIndex = -1; point.pointRead.childLastIndex = -1; point.pointDepthRateMaxPointDepth = 1; maxPointDepth = point.depth; return; } } point.pointRead.childFirstIndex = allPointList.Count; //OYM:记录第一个子节点的位置 point.pointRead.childLastIndex = point.pointRead.childFirstIndex + point.childNode.Count; //OYM:记录最后一个子节点的位置 maxPointDepth = point.depth; //OYM:广度遍历 for (int i = 0; i < point.childNode.Count; i++) { ADBRuntimePoint childPoint = point.childNode[i]; childPoint.pointRead.parentIndex = point.index; childPoint.pointRead.fixedIndex = point.pointRead.fixedIndex; childPoint.parent = point; childPoint.pointRead.initialLocalPosition = Quaternion.Inverse(point.trans.rotation) * (childPoint.trans.position - point.trans.position); childPoint.pointRead.initialLocalRotation = childPoint.trans.localRotation; childPoint.pointRead.initialRotation = childPoint.trans.rotation; childPoint.index = allPointList.Count; if (childPoint.isFixed) { childPoint.pointRead.fixedIndex = childPoint.index; childPoint.pointRead.initialPosition = Vector3.zero; } else { childPoint.pointRead.fixedIndex = point.pointRead.fixedIndex; var fixedPoint = allPointList[childPoint.pointRead.fixedIndex]; childPoint.pointRead.initialPosition = Quaternion.FromToRotation(Vector3.down, aDBSetting.gravity) * Quaternion.Inverse(fixedPoint.trans.rotation) * (childPoint.trans.position - fixedPoint.trans.position); } allPointList.Add(childPoint); } for (int i = 0; i < point.childNode.Count; i++) { int maxDeep = point.depth; SerializeAndSearchAllPoints(point.childNode[i], ref allPointList, out maxDeep); if (maxDeep > maxPointDepth) { maxPointDepth = maxDeep; point.pointDepthRateMaxPointDepth = point.depth / (float)maxDeep; } } }
public void SetParent(ADBRuntimePoint point) { pointRead.parentIndex = point.index; this.parent = point; }