/// <summary> /// Casts a ray starting from origin going along direction up until the maxDistance is reached, meanwhile hitting all entities specified by entityFlags. /// Returns true if an entity is hit, otherwise false. If a hit is registered details about the hit are returned in raycastHit. /// </summary> /// <param name="origin"></param> /// <param name="direction"></param> /// <param name="maxDistance"></param> /// <param name="entityFlags"></param> /// <param name="raycastHit"></param> /// <param name="skipList"></param> /// <returns></returns> public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance, EntityRaycastFlags entityFlags, out RaycastHit raycastHit, params PhysicsEntity[] skipList) { raycastHit = default(RaycastHit); var magnitude = direction.Dot(direction); if (magnitude > 1.0f || magnitude < 1.0f) { direction = direction.Normalized; } var rayParams = new IPhysicalWorld.SRWIParams(); rayParams.org = origin; rayParams.dir = direction * maxDistance; rayParams.objtypes = (int)entityFlags; rayParams.flags = DefaultRaycastFlags; rayParams.nMaxHits = 1; rayParams.hits = new ray_hit(); if (skipList != null && skipList.Length > 0) { rayParams.AllocateSkipEnts(skipList.Length); for (int i = 0; i < skipList.Length; ++i) { rayParams.SetSkipEnt(i, skipList[i].NativeHandle); } } else { rayParams.AllocateSkipEnts(0); } var hits = Global.gEnv.pPhysicalWorld.RayWorldIntersection(rayParams); if (hits > 0) { var hit = rayParams.hits; float u = 0; float v = 0; var entityId = Global.gEnv.pRenderer.GetDetailedRayHitInfo(hit.pCollider, origin, direction, maxDistance, ref u, ref v); raycastHit = new RaycastHit { Distance = hit.dist, Point = hit.pt, Normal = hit.n, TriangleIndex = hit.iPrim, EntityId = entityId, UvPoint = new Vec2(u, v) }; } rayParams.DeleteSkipEnts(); return(hits > 0); }
/// <summary> /// Casts a ray starting from origin going along direction up until the maxDistance is reached, meanwhile hitting all entities specified by entityFlags. /// Returns true if an entity is hit, otherwise false. /// </summary> /// <param name="origin"></param> /// <param name="direction"></param> /// <param name="maxDistance"></param> /// <param name="entityFlags"></param> /// <param name="skipList"></param> /// <returns></returns> public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance, EntityRaycastFlags entityFlags, params IPhysicalEntity[] skipList) { var magnitude = direction.Dot(direction); if (magnitude > 1.0f || magnitude < 1.0f) { direction = direction.Normalized; } var rayParams = new IPhysicalWorld.SRWIParams(); rayParams.org = origin; rayParams.dir = direction * maxDistance; rayParams.objtypes = (int)entityFlags; rayParams.flags = DefaultRaycastFlags; rayParams.nMaxHits = 1; rayParams.hits = new ray_hit(); if (skipList != null) { rayParams.AllocateSkipEnts(skipList.Length); for (int i = 0; i < skipList.Length; ++i) { rayParams.SetSkipEnt(i, skipList[i]); } } else { rayParams.AllocateSkipEnts(0); } var hits = Global.gEnv.pPhysicalWorld.RayWorldIntersection(rayParams); rayParams.DeleteSkipEnts(); return(hits > 0); }