Module: Jolt::SystemContacts

Included in:
System
Defined in:
lib/jolt/system_contacts.rb

Constant Summary collapse

CONTACT_EVENT_TYPES =
%i[added persisted removed].freeze
MAX_CONTACT_QUEUE_CAPACITY =
1 << 30

Instance Method Summary collapse

Instance Method Details

#__create_contact_queue(capacity) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/jolt/system_contacts.rb', line 8

def __create_contact_queue(capacity)
  unless capacity.is_a?(Integer) && capacity.between?(2, MAX_CONTACT_QUEUE_CAPACITY)
    raise InvalidArgumentError,
          "contact_queue_capacity must be an integer between 2 and #{MAX_CONTACT_QUEUE_CAPACITY}"
  end

  @contact_queue = Native.JR_ContactQueue_Create(capacity)
  raise InitializationError, "failed to create contact event queue" if @contact_queue.null?

  listener = Native.JR_ContactQueue_GetListener(@contact_queue)
  raise InitializationError, "failed to create contact listener" if listener.null?

  Native.JPH_PhysicsSystem_SetContactListener(@pointer, listener)
  @contact_events = ContactEvents.empty
end

#__destroy_contact_queueObject



49
50
51
52
53
54
55
# File 'lib/jolt/system_contacts.rb', line 49

def __destroy_contact_queue
  return unless @contact_queue && !@contact_queue.null?

  Native.JPH_PhysicsSystem_SetContactListener(@pointer, nil) if @pointer && !@pointer.null?
  Native.JR_ContactQueue_Destroy(@contact_queue)
  @contact_queue = nil
end

#__drain_contact_eventsObject



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/jolt/system_contacts.rb', line 24

def __drain_contact_events
  grouped = {added: [], persisted: [], removed: []}
  native = Native::ContactEvent.new
  while Native.JR_ContactQueue_Pop(@contact_queue, native.pointer)
    type = CONTACT_EVENT_TYPES.fetch(native[:type])
    removed = type == :removed
    grouped.fetch(type) << Contact.new(
      body_a: @body_registry[native[:body_a]],
      body_b: @body_registry[native[:body_b]],
      sub_shape_a: native[:sub_shape_a],
      sub_shape_b: native[:sub_shape_b],
      point: removed ? nil : Larb::Vec3.new(*native[:point].to_a),
      normal: removed ? nil : Larb::Vec3.new(*native[:normal].to_a),
      penetration: removed ? nil : native[:penetration]
    )
  end
  dropped = Native.JR_ContactQueue_GetDroppedCount(@contact_queue)
  @contact_events = ContactEvents.new(
    added: grouped[:added].freeze,
    persisted: grouped[:persisted].freeze,
    removed: grouped[:removed].freeze,
    dropped_count: dropped
  )
end