/// <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); }
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); }
/// <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); } }
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)); }
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); } }
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 }
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 }