public void Raycast(RayOctreeQuery query, bool single = false) { query.Results.Clear(); if (query.Ray == null) { return; } int count; IntPtr resultVector; var ptr = csi_Atomic_Octree_Raycast(nativeInstance, ref query.Ray, ref query.Level, query.MaxDistance, query.DrawableFlags, query.ViewMask, single, out resultVector, out count); if (ptr == IntPtr.Zero) { return; } int structSize = Marshal.SizeOf(typeof(RayQueryResult)); for (int i = 0; i < count; i++) { IntPtr data = new IntPtr(ptr.ToInt64() + structSize * i); RayQueryResult item = (RayQueryResult)Marshal.PtrToStructure(data, typeof(RayQueryResult)); query.Results.Add(item); } csi_Atomic_Octree_Raycast_FreeResult(resultVector); }
public void Raycast(RayOctreeQuery query, bool single = false) { query.Results.Clear(); if (query.Ray == null) return; int count; IntPtr resultVector; var ptr = csi_Atomic_Octree_Raycast(nativeInstance, ref query.Ray, ref query.Level, query.MaxDistance, query.DrawableFlags, query.ViewMask, single, out resultVector, out count); if (ptr == IntPtr.Zero) { return; } int structSize = Marshal.SizeOf(typeof(RayQueryResult)); for (int i = 0; i < count; i++) { IntPtr data = new IntPtr(ptr.ToInt64() + structSize * i); RayQueryResult item = (RayQueryResult)Marshal.PtrToStructure(data, typeof(RayQueryResult)); query.Results.Add(item); } csi_Atomic_Octree_Raycast_FreeResult(resultVector); }
bool Raycast(float maxDistance, out Vector3 hitPos, out Drawable hitDrawable) { var input = GetSubsystem<Input>(); hitDrawable = null; hitPos = new Vector3(); var graphics = GetSubsystem<Graphics>(); Camera camera = CameraNode.GetComponent<Camera>(); IntVector2 pos = input.MousePosition; Ray cameraRay = camera.GetScreenRay((float)pos.X / graphics.Width, (float)pos.Y / graphics.Height); RayOctreeQuery query = new RayOctreeQuery(cameraRay, RayQueryLevel.RAY_TRIANGLE, maxDistance, Constants.DRAWABLE_GEOMETRY); // Pick only geometry objects, not eg. zones or lights, only get the first (closest) hit scene.GetComponent<Octree>().RaycastSingle(query); if (query.Results.Count > 0) { var first = query.Results.First(); hitPos = first.Position; hitDrawable = first.Drawable; return true; } return false; }
/// Return the closest drawable object by a ray query. public void RaycastSingle(RayOctreeQuery query) { Raycast(query, true); }
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; }); }