private unsafe void UpdateWheels(TrackMarksBuilderComponent builder, ChassisAnimationComponent chassis, TrackMarksRenderComponent render, TrackMarksComponent trackMarks, int track, WheelData[] currentWheelsPositions, WheelData[] prevWheelsPosition, WheelData[] temp) { float highDistance = chassis.highDistance; WheelData data = prevWheelsPosition[prevWheelsPosition.Length / 2]; WheelData data2 = currentWheelsPositions[currentWheelsPositions.Length / 2]; float num2 = (data.position - data2.position).magnitude + builder.remaingDistance[track]; int num3 = (int)(num2 / builder.moveStep); Vector3 lhs = Vector3.Cross(trackMarks.transform.up, this.GetVelocity(builder) * Time.smoothDeltaTime).normalized *builder.side[track]; float b = Mathf.Max(Mathf.Abs(Vector3.Dot(lhs, this.ComputeTrackDiagonal(builder, trackMarks, currentWheelsPositions, ref lhs))) / 2f, trackMarks.markWidth); float a = Mathf.Max(Mathf.Abs(Vector3.Dot(lhs, this.ComputeTrackDiagonal(builder, trackMarks, prevWheelsPosition, ref lhs))) / 2f, trackMarks.markWidth); bool flag = false; RaycastHit hit = new RaycastHit(); for (int i = 0; i < num3; i++) { float t = ((float)i) / ((float)num3); float width = Mathf.Lerp(a, b, t); float num9 = Mathf.Min((float)(width / trackMarks.markWidth), (float)2f); this.InterpolateWheelsPosition(t, prevWheelsPosition, currentWheelsPositions, temp); flag = this.IsHit(builder, trackMarks, temp, highDistance, out hit); RaycastHit *hitPtr1 = &hit; hitPtr1.point -= (builder.side[track] * trackMarks.transform.right) * trackMarks.shiftToCenter; this.UpdateTrack(builder, render, trackMarks, track, flag, ref hit, width, num9 - 1f); num2 -= builder.moveStep; } builder.remaingDistance[track] = num2; }
/// <summary> /// Casts a ray through the world and returns all intersections. /// </summary> /// <param name="pos"> Position from which to cast a ray.</param> /// <param name="dir"> Direction of the ray to cast.</param> /// <param name="objectTypes"> /// Flags that define which objects to query for intersection with this ray. /// </param> /// <param name="flags"> Flags that define how to detect intersections.</param> /// <param name="maxHits"> Maximal number of hits to return.</param> /// <param name="skipEntities">An array of IPhysicalEntity handles.</param> /// <returns>Detected hits (solid and pierceable).</returns> public unsafe static List <RaycastHit> Cast ( Vector3 pos, Vector3 dir, EntityQueryFlags objectTypes = EntityQueryFlags.All, RayWorldIntersectionFlags flags = RayWorldIntersectionFlags.AnyHit, int maxHits = 1, IntPtr[] skipEntities = null ) { if (maxHits < 1) { return(null); } List <RaycastHit> hits; // Allocate memory for entities to skip. using (NativeMemoryBlock skipEntitiesArray = new NativeMemoryBlock(skipEntities == null ? 0 : skipEntities.Length, typeof(IntPtr))) // Allocate memory for ray-cast hits. using (NativeMemoryBlock hitsArray = new NativeMemoryBlock(maxHits, typeof(RaycastHit))) { // Transfer handles of entities to skip to native memory. if (!skipEntitiesArray.Disposed) { IntPtr *skipEntsPointer = (IntPtr *)skipEntitiesArray.Handle.ToPointer(); for (int i = 0; i < skipEntities.Length; i++) // Ignore that ReSharper warning. { skipEntsPointer[i] = skipEntities[i]; } } // Cast the ray. int numberOfHits = Native.PhysicsInterop.RayWorldIntersection ( pos, dir, objectTypes, flags, maxHits, skipEntitiesArray.Handle, skipEntities == null ? 0 : skipEntities.Length, hitsArray.Handle ); // Transfer ray-cast hits from native memory. RaycastHit *hitPointer = (RaycastHit *)hitsArray.Handle.ToPointer(); hits = new List <RaycastHit>(numberOfHits); for (int i = 0; i < numberOfHits; i++) { hits.Add(hitPointer[i]); } } return(hits); }