Beispiel #1
0
        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);
        }