/// <summary>
        /// Get decal property from DecalProperties in compliance ContactPoint surface.
        /// </summary>
        public static DecalProperty GetDecalPropertyBySurface(DecalProperties decalProperties, ContactPoint contactPoint)
        {
            if (decalProperties == null)
            {
                return(DecalProperty.Empty);
            }

            Object surfaceInfo = null;

            for (int i = 0, length = decalProperties.GetLength(); i < length; i++)
            {
                DecalProperty decalProperty = decalProperties.GetProperty(i);

                if (decalProperty.GetTexture() != null)
                {
                    surfaceInfo = SurfaceHelper.GetSurfaceTexture(contactPoint.thisCollider, contactPoint.point);
                    if (surfaceInfo == decalProperty.GetTexture())
                    {
                        return(decalProperties.GetProperty(i));
                    }
                }

                if (decalProperty.GetPhysicMaterial() != null)
                {
                    surfaceInfo = SurfaceHelper.GetSurfaceMaterial(contactPoint.thisCollider, contactPoint.point);
                    if (surfaceInfo == decalProperty.GetPhysicMaterial())
                    {
                        return(decalProperties.GetProperty(i));
                    }
                }
            }
            return(DecalProperty.Empty);
        }
Пример #2
0
        public override GeoPoint2D PositionOf(GeoPoint p)
        {
            GeoPoint2D uvp = periodicSurface.PositionOf(p);

            SurfaceHelper.AdjustPeriodic(periodicSurface, periodicBounds, ref uvp);
            return(fromPeriodic(uvp));
        }
        /// <summary>
        /// Returning step sound by current surface on which is stand AI.
        /// </summary>
        /// <returns>AudioClip: Step sound</returns>
        public virtual AudioClip GetStepSound()
        {
            if (footstepProperties == null || footstepProperties.GetLength() == 0)
            {
                return(null);
            }

            RaycastHit footstepshit;

            if (Physics.Raycast(transform.position, Vector3.down, out footstepshit))
            {
                Object surfaceInfo = SurfaceHelper.GetSurfaceAuto(footstepshit.collider, transform.position);
                if (!surfaceInfo)
                {
                    return(null);
                }

                for (int i = 0; i < footstepProperties.GetLength(); i++)
                {
                    if (footstepProperties.GetProperty(i).GetPhysicMaterial() == surfaceInfo || footstepProperties.GetProperty(i).GetTexture() == surfaceInfo)
                    {
                        if (footstepProperties.GetProperty(i).GetStepSoundsLength() > 0)
                        {
                            int randomSound = Random.Range(0, footstepProperties.GetProperty(i).GetStepSoundsLength());
                            return(footstepProperties.GetProperty(i).GetStepSound(randomSound));
                        }
                    }
                }
            }
            return(null);
        }
Пример #4
0
 /// <summary>
 /// Returns the type of surface at the given position on the terrain.
 /// </summary>
 public SurfaceType GetSurface(Vector3 position, GameObject obj)
 {
     if (surface != null)
     {
         if (obj.GetComponent <Terrain>() != null)
         {
             return(surface[SurfaceHelper.GetMainTexture(position, terrain.transform.position, terrain.terrainData)].GetSurface());
         }
         else
         {
             return(surface[0].GetSurface());
         }
     }
     else
     {
         return(SurfaceType.Default);
     }
 }
Пример #5
0
        public ISurface AdaptToCurves(IEnumerable <ICurve> curves)
        {
            BoundingRect domain = BoundingRect.EmptyBoundingRect;

            foreach (ICurve curve in curves)
            {
                ICurve2D c2d = periodicSurface.GetProjectedCurve(curve, 0.0);
                if (domain.IsEmpty())
                {
                    domain = c2d.GetExtent();
                }
                else
                {
                    SurfaceHelper.AdjustPeriodic(periodicSurface, domain, c2d);
                    domain.MinMax(c2d.GetExtent());
                }
            }
            return(new NonPeriodicSurface(periodicSurface, domain));
        }
Пример #6
0
        protected override void GetTriangulationBasis(out GeoPoint2D[] points, out GeoVector2D[] directions, out double[] parameters)
        {
            double[]      pars      = curve3D.GetSavePositions();
            List <double> positions = new List <double>();

            for (int i = 0; i < pars.Length; i++)
            {
                double d = Get2dParameter(pars[i]);
                if (d > 1e-6 && d < 1.0 - 1e-6)
                {
                    positions.Add(d);                             // nur innerhalb des Bereichs und 0 und 1 nicht doppelt
                }
            }
            positions.Add(0.0);
            positions.Add(1.0);
            if (positions.Count < 3)
            {
                positions.Add(0.5);
            }
            positions.Sort();
            List <double> lparameters = new List <double>();

            for (int i = 0; i < positions.Count; i++)
            {
                lparameters.Add(positions[i]);
            }
            List <GeoPoint2D>  lpoints     = new List <GeoPoint2D>();
            List <GeoVector2D> ldirections = new List <GeoVector2D>();

            for (int i = 0; i < positions.Count; i++)
            {
                GeoPoint2D  p;
                GeoVector2D v;
                PointDirAt(positions[i], out p, out v);
                lpoints.Add(p);
                ldirections.Add(v);
            }

            bool check = true;

            // the interpolation should be smooth. Max. bending between interpolation points 45°, which makes sure, the baseApproximation
            // uses arcs, so that the start- and end-direction are correct
            while (check && lpoints.Count < 100)
            {
                check = false;
                for (int i = lpoints.Count - 1; i > 0; --i)
                {
                    if (Math.Abs(new SweepAngle(ldirections[i], ldirections[i - 1])) > Math.PI / 4)
                    {
                        double      par = (positions[i] + positions[i - 1]) / 2.0;
                        GeoPoint2D  p   = PointAt(par);
                        GeoVector2D dir = DirectionAt(par);
                        lpoints.Insert(i, p);
                        ldirections.Insert(i, dir);
                        positions.Insert(i, par);
                        check = true;
                    }
                }
            }
            points     = lpoints.ToArray();
            directions = ldirections.ToArray();
            parameters = positions.ToArray();
            if (surface.IsUPeriodic)
            {
                for (int i = 1; i < points.Length; i++)
                {
                    if ((points[i].x - points[i - 1].x) > surface.UPeriod / 2.0)
                    {
                        points[i].x -= surface.UPeriod;
                    }
                    if ((points[i].x - points[i - 1].x) < -surface.UPeriod / 2.0)
                    {
                        points[i].x += surface.UPeriod;
                    }
                }
            }
            if (surface.IsVPeriodic)
            {
                for (int i = 1; i < points.Length; i++)
                {
                    if ((points[i].y - points[i - 1].y) > surface.VPeriod / 2.0)
                    {
                        points[i].y -= surface.VPeriod;
                    }
                    if ((points[i].y - points[i - 1].y) < -surface.VPeriod / 2.0)
                    {
                        points[i].y += surface.VPeriod;
                    }
                }
            }
            if (!periodicDomain.IsEmpty())
            {
                SurfaceHelper.AdjustPeriodic(surface, periodicDomain, points);
            }
        }
Пример #7
0
        private int debugCount; // to identify instance when debugging
#endif

        public ProjectedCurve(ICurve curve3D, ISurface surface, bool forward, BoundingRect domain, double precision = 0.0)
        {
#if DEBUG
            debugCount = debugCounter++;
#endif
            this.curve3D = curve3D; // keep in mind, the curve is not cloned, curve3D should not be modified after this
            this.surface = surface;
            List <GeoPoint>   lpoles   = new List <GeoPoint>();
            List <GeoPoint2D> lpoles2d = new List <GeoPoint2D>();
            GeoPoint2D        cnt2d    = domain.GetCenter();
            GeoPoint          sp       = curve3D.StartPoint;
            GeoPoint          ep       = curve3D.EndPoint;
            double[]          us       = surface.GetUSingularities();
            double            prec     = precision;
            if (prec == 0.0)
            {
                prec = curve3D.Length * 1e-3;              // changed to 1e-3, it is used to snap endpoints to poles
            }
            startPoint2d = surface.PositionOf(curve3D.StartPoint);
            endPoint2d   = surface.PositionOf(curve3D.EndPoint);
            bool distinctStartEndPoint = false;
            if ((surface.IsUPeriodic && Math.Abs(startPoint2d.x - endPoint2d.x) < surface.UPeriod * 1e-3) ||
                (surface.IsVPeriodic && Math.Abs(startPoint2d.y - endPoint2d.y) < surface.VPeriod * 1e-3))
            {   // adjust start and endpoint according to its neighbors
                GeoPoint2D p2d = surface.PositionOf(curve3D.PointAt(0.1));
                SurfaceHelper.AdjustPeriodic(surface, periodicDomain, ref p2d);
                BoundingRect ext = new BoundingRect(p2d);
                SurfaceHelper.AdjustPeriodic(surface, ext, ref startPoint2d);
                p2d = surface.PositionOf(curve3D.PointAt(0.9));
                SurfaceHelper.AdjustPeriodic(surface, periodicDomain, ref p2d);
                ext = new BoundingRect(p2d);
                SurfaceHelper.AdjustPeriodic(surface, ext, ref endPoint2d);
                distinctStartEndPoint = true;
            }
            periodicDomain = domain;
            if (periodicDomain.IsEmpty() && (surface.IsUPeriodic || surface.IsVPeriodic))
            {
                // make a few points and assure that they don't jump over the periodic seam
                // if the curve3d doesn't jump around wildly, this should work. Maybe use curve3D.GetSavePositions?
                GeoPoint2D[] point2Ds = new GeoPoint2D[11];
                for (int i = 0; i < 11; i++)
                {
                    point2Ds[i] = surface.PositionOf(curve3D.PointAt(i / 10.0));
                }
                for (int i = 0; i < 10; i++)
                {
                    GeoVector2D offset = GeoVector2D.NullVector;
                    if (surface.IsUPeriodic && Math.Abs(point2Ds[i + 1].x - point2Ds[i].x) > surface.UPeriod / 2.0)
                    {
                        if ((point2Ds[i + 1].x - point2Ds[i].x) < 0)
                        {
                            offset.x = surface.UPeriod;
                        }
                        else
                        {
                            offset.x = -surface.UPeriod;
                        }
                    }
                    if (surface.IsVPeriodic && Math.Abs(point2Ds[i + 1].y - point2Ds[i].y) > surface.VPeriod / 2.0)
                    {
                        if ((point2Ds[i + 1].y - point2Ds[i].y) < 0)
                        {
                            offset.y = surface.VPeriod;
                        }
                        else
                        {
                            offset.y = -surface.VPeriod;
                        }
                    }
                    point2Ds[i + 1] += offset;
                }
                for (int i = 0; i < 11; i++)
                {
                    periodicDomain.MinMax(point2Ds[i]);
                }
                startPoint2d = point2Ds[0];
                endPoint2d   = point2Ds[10];
            }
            if (!periodicDomain.IsEmpty() && (!surface.IsUPeriodic || periodicDomain.Width < surface.UPeriod * (1 - 1e-6)) && (!surface.IsVPeriodic || periodicDomain.Height < surface.VPeriod * (1 - 1e-6)))
            {
                SurfaceHelper.AdjustPeriodic(surface, periodicDomain, ref startPoint2d);
                SurfaceHelper.AdjustPeriodic(surface, periodicDomain, ref endPoint2d);
            }
            startPointIsPole = endPointIsPole = false;
            for (int i = 0; i < us.Length; i++)
            {
                GeoPoint pl = surface.PointAt(new GeoPoint2D(us[i], cnt2d.y));
                if ((pl | sp) < prec)
                {
                    GeoPoint2D tmp = surface.PositionOf(curve3D.PointAt(0.1));
                    startPoint2d     = new GeoPoint2D(us[i], tmp.y);
                    startPointIsPole = true;
                    spu = true;
                }
                if ((pl | ep) < prec)
                {
                    GeoPoint2D tmp = surface.PositionOf(curve3D.PointAt(0.9));
                    endPoint2d     = new GeoPoint2D(us[i], tmp.y);
                    endPointIsPole = true;
                    epu            = true;
                }
            }
            double[] vs = surface.GetVSingularities();
            for (int i = 0; i < vs.Length; i++)
            {
                GeoPoint pl = surface.PointAt(new GeoPoint2D(cnt2d.x, vs[i]));
                if ((pl | sp) < prec)
                {
                    GeoPoint2D tmp = surface.PositionOf(curve3D.PointAt(0.1));
                    startPoint2d     = new GeoPoint2D(tmp.x, vs[i]);
                    startPointIsPole = true;
                    spu = false;
                }
                if ((pl | ep) < prec)
                {
                    GeoPoint2D tmp = surface.PositionOf(curve3D.PointAt(0.9));
                    endPoint2d     = new GeoPoint2D(tmp.x, vs[i]);
                    endPointIsPole = true;
                    epu            = false;
                }
            }
            if (forward)
            {
                startParam = 0.0;
                endParam   = 1.0;
            }
            else
            {
                startParam = 1.0;
                endParam   = 0.0;
            }
#if DEBUG
            this.MakeTriangulation();
#endif
        }
Пример #8
0
        public override int GetExtremePositions(BoundingRect thisBounds, ISurface other, BoundingRect otherBounds, out List <Tuple <double, double, double, double> > extremePositions)
        {
            switch (other)
            {
            case SphericalSurface ss:
            {
                GeoPoint2D fp = PositionOf(ss.Location);
                extremePositions = new List <Tuple <double, double, double, double> >();
                extremePositions.Add(new Tuple <double, double, double, double>(fp.x, fp.y, double.NaN, double.NaN));
                return(1);
            }

            case ToroidalSurface ts:
            {
                GeoVector dir = (ts.ZAxis ^ Normal) ^ ts.ZAxis;         // this is the direction of a line from the center of the torus where the u positions of the extereme position of the torus are
                if (dir.IsNullVector())
                {
                    break;
                }
                GeoPoint2D[] ip = ts.GetLineIntersection(ts.Location, dir);         // the result should be 4 points, but we are interested in u parameters only and this must be u and u+pi
                if (ip != null && ip.Length > 0)
                {
                    extremePositions = new List <Tuple <double, double, double, double> >();
                    double u = ip[0].x;
                    SurfaceHelper.AdjustUPeriodic(ts, otherBounds, ref u);
                    if (u >= otherBounds.Left && u <= otherBounds.Right)
                    {
                        extremePositions.Add(new Tuple <double, double, double, double>(double.NaN, double.NaN, u, double.NaN));
                    }
                    u += Math.PI;
                    SurfaceHelper.AdjustUPeriodic(ts, otherBounds, ref u);
                    if (u >= otherBounds.Left && u <= otherBounds.Right)
                    {
                        extremePositions.Add(new Tuple <double, double, double, double>(double.NaN, double.NaN, u, double.NaN));
                    }
                    return(extremePositions.Count);
                }
            }
            break;

            case PlaneSurface ps:
            case CylindricalSurface cys:
            case ConicalSurface cos:
                extremePositions = null;
                return(0);

            case ISurfaceImpl ns:
            {
                GeoPoint2D[] normals = ns.BoxedSurfaceEx.PositionOfNormal(Normal);
                extremePositions = new List <Tuple <double, double, double, double> >();
                for (int i = 0; i < normals.Length; i++)
                {
                    if (otherBounds.Contains(normals[i]))
                    {
                        extremePositions.Add(new Tuple <double, double, double, double>(double.NaN, double.NaN, normals[i].x, normals[i].y));
                    }
                }
            }
            break;
            }
            extremePositions = null;
            return(-1); // means: no implementation for this combination
        }