private float GetAddPointFactorInRefTo(Vector3 pPoint, Vector3 pReferencePoint, bool pSameBranch, bool pMerging, CTree pTreeToMerge = null) { //during merging it is expected, that added peak will be higher if (!pMerging && pPoint.Z > pReferencePoint.Z) { //points are added in descending order. if true => pPoint belongs to another tree return(0); } float pointDistToRef = Vector3.Distance(pPoint, pReferencePoint); if (pointDistToRef < 0.2) { return(1); } float refDistToPeak = CUtils.Get2DDistance(pReferencePoint, tree.peak); float pointDistToPeak = CUtils.Get2DDistance(pPoint, tree.peak); if (!pMerging && pSameBranch) { if (pointDistToPeak < refDistToPeak) { return(1); } } float distToPeakDiff = pointDistToPeak - refDistToPeak; if (!pMerging && distToPeakDiff < 0.3) { return(1); } if (!pMerging && distToPeakDiff > 0.5f && refDistToPeak > 0.5f) { float peakRefPointAngle = CUtils.AngleBetweenThreePoints(tree.peak.Center, pReferencePoint, pPoint); //new point is too far from furthest point and goes too much out of direction of peak->furthestPoint if (peakRefPointAngle < 180 - 45) { return(0); } } float refAngleToPoint = CUtils.AngleBetweenThreePoints(pReferencePoint - Vector3.UnitZ, pReferencePoint, pPoint); Vector3 suitablePeakPoint = tree.peak.Center; float peakAngleToPoint = CUtils.AngleBetweenThreePoints(suitablePeakPoint - Vector3.UnitZ, suitablePeakPoint, pPoint); float angle = Math.Min(refAngleToPoint, peakAngleToPoint); float maxBranchAngle = CTree.GetMaxBranchAngle(suitablePeakPoint, pPoint); float unacceptableAngle = maxBranchAngle; if (!pMerging && angle > unacceptableAngle) { return(0); } unacceptableAngle += 30; unacceptableAngle = Math.Min(unacceptableAngle, 100); float angleFactor = (unacceptableAngle - angle) / unacceptableAngle; float unacceptableDistance = tree.GetTreeExtentFor(pPoint, pMerging ? CParameterSetter.treeExtentMultiply : 1); unacceptableDistance += 0.5f; if (pointDistToPeak > unacceptableDistance) { return(0); } unacceptableDistance += 0.5f; float distFactor = (unacceptableDistance - pointDistToPeak) / unacceptableDistance; Vector3 closestPoint = GetClosestPointTo(pPoint); float distFromClosestPoint = Vector3.Distance(pPoint, closestPoint); float maxDistFromClosest = 0.5f; float distToClosestFactor = 2 * (maxDistFromClosest + 0.2f - distFromClosestPoint); distToClosestFactor = Math.Max(0, distToClosestFactor); float totalFactor; if (pMerging) { if (distFromClosestPoint < maxDistFromClosest && distToPeakDiff < maxDistFromClosest) { return(1); } } if (pTreeToMerge != null && pMerging && pTreeToMerge.isValid) { int factorCount = 3; if (distToClosestFactor < .1f) { factorCount -= 1; } totalFactor = (distToClosestFactor + angleFactor + distFactor) / factorCount; } else { //let dist factor have higher influence totalFactor = (angleFactor + 1.5f * distFactor) / 2.5f; } return(totalFactor); }