internal static extern IntPtr csi_Atomic_Octree_Raycast(IntPtr self, ref Ray ray, ref RayQueryLevel level, float maxDistance, uint drawableFlags, uint viewMask, bool single, out IntPtr resultVector, out int count);
/// Construct with ray and query parameters. public RayOctreeQuery(Ray ray, RayQueryLevel level = RayQueryLevel.RAY_TRIANGLE, float maxDistance = Single.PositiveInfinity, uint drawableFlags = Constants.DRAWABLE_ANY, uint viewMask = Constants.DEFAULT_VIEWMASK) { this.Ray = ray; this.Level = level; this.MaxDistance = maxDistance; this.DrawableFlags = drawableFlags; this.ViewMask = viewMask; }
public Vector3 ClosestPoint(Ray otherRay) { var p13 = Origin - otherRay.Origin; var p43 = otherRay.Direction; Vector3 p21 = Direction; float d1343 = Vector3.Dot(p13, p43); float d4321 = Vector3.Dot(p43, p21); float d1321 = Vector3.Dot(p13, p21); float d4343 = Vector3.Dot(p43, p43); float d2121 = Vector3.Dot(p21, p21); float d = d2121 * d4343 - d4321 * d4321; if (Math.Abs(d) < float.Epsilon) return Origin; float n = d1343 * d4321 - d1321 * d4343; float a = n / d; return Origin + a * Direction; }
private static extern void csi_Atomic_Camera_GetScreenRay(IntPtr self, float x, float y, ref Ray retValue);
void SubscribeToEvents() { SubscribeToEvent<PostUpdateEvent>(e => { if (vehicle == null) return; Node vehicleNode = vehicle.Node; // Physics update has completed. Position camera behind vehicle Quaternion dir = Quaternion.FromAxisAngle(Vector3.UnitY, vehicleNode.Rotation.YawAngle); dir = dir * Quaternion.FromAxisAngle(Vector3.UnitY, vehicle.Controls.Yaw); dir = dir * Quaternion.FromAxisAngle(Vector3.UnitX, vehicle.Controls.Pitch); Vector3 cameraTargetPos = vehicleNode.Position - (dir * new Vector3(0.0f, 0.0f, CameraDistance)); Vector3 cameraStartPos = vehicleNode.Position; // and move it closer to the vehicle if something in between Ray cameraRay = new Ray(cameraStartPos, cameraTargetPos - cameraStartPos); float cameraRayLength = (cameraTargetPos - cameraStartPos).Length; // Raycast camera against static objects (physics collision mask 2) var query = new RayOctreeQuery(cameraRay, RayQueryLevel.RAY_TRIANGLE, cameraRayLength, Constants.DRAWABLE_ANY, 2); PhysicsRaycastResult result = new PhysicsRaycastResult(); scene.GetComponent<PhysicsWorld>().RaycastSingle(ref result, cameraRay, cameraRayLength, 2); if (result.Body != null) { cameraTargetPos = cameraStartPos + cameraRay.Direction * (result.Distance - 0.5f); } CameraNode.Position = cameraTargetPos; CameraNode.Rotation = dir; }); }
internal static extern IntPtr csi_Atomic_PhysicsWorld_RaycastSingle(IntPtr self, ref Ray ray, float maxDistance, uint collisionMask, out PhysicsRaycastResult result);
public void RaycastSingle(ref PhysicsRaycastResult result, Ray ray, float maxDistance, uint collisionMask = uint.MaxValue) { csi_Atomic_PhysicsWorld_RaycastSingle(nativeInstance, ref ray, maxDistance, collisionMask, out result); }