use super::streams::RigidStream;
use super::{CONTACT, IDENTITY};
use crate::RigidFrame;
use dynamis_abi::Count;
use dynamis_abi::{
COUNTER_ARCHIVED, COUNTER_CONTACTS, COUNTER_EVENTS, COUNTER_RESTING, COUNTER_RESTING_INDEX,
COUNTER_SLEPT, COUNTER_SPILLOVER_EVENTS, COUNTER_WOKE, COUNTER_WOKE_DEFERRED,
};
use dynamis_gpu::Resources;
use dynamis_gpu::{ComputeRecorder, GpuContext};
use dynamis_pass::Stage;
use dynamis_shader::{CORE, rows, stream};
use dynamis_state::StateStream;
pub struct Islands {
contact_relay: Stage,
contact_begin: Stage,
island_init: Stage,
island_link_contacts: Stage,
island_link_constraints: Stage,
island_link_resting: Stage,
island_jump: Stage,
island_aggregate: Stage,
island_wake: Stage,
}
pub struct Sleep {
island_sleep: Stage,
}
impl Islands {
pub fn build(context: &GpuContext, streams: &impl Resources) -> Self {
Self {
contact_relay: Stage::build(
context,
"contact_relay",
stream(
context,
include_str!("../shaders/contact_relay.wgsl"),
CONTACT,
"work",
RigidStream::ContactArchive,
),
streams,
&[
("archive", RigidStream::ContactArchive.whole()),
("archive_count", dynamis_state::counter(COUNTER_ARCHIVED)),
("contacts", RigidStream::Contacts.whole()),
("contact_count", dynamis_state::counter(COUNTER_CONTACTS)),
("contact_matched", RigidStream::ContactMatched.whole()),
("events", RigidStream::Events.whole()),
("event_count", dynamis_state::counter(COUNTER_EVENTS)),
(
"spillover",
dynamis_state::counter(COUNTER_SPILLOVER_EVENTS),
),
("params", StateStream::Params.whole()),
("row_of_body", StateStream::BodyRowOfId.whole()),
("body_states", StateStream::BodyStates.whole()),
("body_descs", StateStream::BodyDescriptors.whole()),
],
&[],
),
contact_begin: Stage::build(
context,
"contact_begin",
stream(
context,
include_str!("../shaders/contact_begin.wgsl"),
CONTACT,
"work",
RigidStream::Contacts,
),
streams,
&[
("contacts", RigidStream::Contacts.whole()),
("contact_count", dynamis_state::counter(COUNTER_CONTACTS)),
("contact_matched", RigidStream::ContactMatched.whole()),
("events", RigidStream::Events.whole()),
("event_count", dynamis_state::counter(COUNTER_EVENTS)),
(
"spillover",
dynamis_state::counter(COUNTER_SPILLOVER_EVENTS),
),
("params", StateStream::Params.whole()),
("resting", RigidStream::RestingContacts.whole()),
("resting_live", RigidStream::RestingLive.whole()),
("resting_major", RigidStream::RestingIndexMajor.whole()),
("resting_minor", RigidStream::RestingIndexMinor.whole()),
("resting_slots", RigidStream::RestingIndexSlots.whole()),
(
"resting_index",
dynamis_state::counter(COUNTER_RESTING_INDEX),
),
],
&[],
),
island_init: Stage::build(
context,
"island_init",
rows(
context,
include_str!("../shaders/island_init.wgsl"),
CORE,
Count::Dynamic.field(),
),
streams,
&[
("params", StateStream::Params.whole()),
("island_parents", RigidStream::IslandParents.whole()),
("island_state", RigidStream::IslandState.whole()),
],
&[],
),
island_link_contacts: Stage::build(
context,
"island_link_contacts",
stream(
context,
include_str!("../shaders/island_link_contacts.wgsl"),
IDENTITY,
"work",
RigidStream::Contacts,
),
streams,
&[
("contacts", RigidStream::Contacts.whole()),
("contact_count", dynamis_state::counter(COUNTER_CONTACTS)),
("island_parents", RigidStream::IslandParents.whole()),
("wake_flags", StateStream::WakeFlags.whole()),
("params", StateStream::Params.whole()),
("collider_owners", StateStream::ColliderOwners.whole()),
],
&[],
),
island_link_constraints: Stage::build(
context,
"island_link_constraints",
rows(
context,
include_str!("../shaders/island_link_constraints.wgsl"),
CORE,
Count::Constraints.field(),
),
streams,
&[
("params", StateStream::Params.whole()),
("constraint_runtime", StateStream::ConstraintRuntime.whole()),
("island_parents", RigidStream::IslandParents.whole()),
("wake_flags", StateStream::WakeFlags.whole()),
("constraint_rows", RigidStream::ConstraintRows.whole()),
],
&[],
),
island_link_resting: Stage::build(
context,
"island_link_resting",
stream(
context,
include_str!("../shaders/island_link_resting.wgsl"),
IDENTITY,
"work",
RigidStream::RestingContacts,
),
streams,
&[
("params", StateStream::Params.whole()),
("resting", RigidStream::RestingContacts.whole()),
("resting_live", RigidStream::RestingLive.whole()),
("resting_count", dynamis_state::counter(COUNTER_RESTING)),
("row_of_body", StateStream::BodyRowOfId.whole()),
("body_states", StateStream::BodyStates.whole()),
("island_parents", RigidStream::IslandParents.whole()),
("wake_flags", StateStream::WakeFlags.whole()),
],
&[],
),
island_jump: Stage::build(
context,
"island_jump",
rows(
context,
include_str!("../shaders/island_jump.wgsl"),
CORE,
Count::Dynamic.field(),
),
streams,
&[
("params", StateStream::Params.whole()),
("island_parents", RigidStream::IslandParents.whole()),
],
&[],
),
island_aggregate: Stage::build(
context,
"island_aggregate",
rows(
context,
include_str!("../shaders/island_aggregate.wgsl"),
CORE,
Count::Dynamic.field(),
),
streams,
&[
("params", StateStream::Params.whole()),
("body_motion", RigidStream::BodyMotion.whole()),
("island_parents", RigidStream::IslandParents.whole()),
("island_state", RigidStream::IslandState.whole()),
("wake_flags", StateStream::WakeFlags.whole()),
],
&[],
),
island_wake: Stage::build(
context,
"island_wake",
rows(
context,
include_str!("../shaders/island_wake.wgsl"),
CORE,
Count::Dynamic.field(),
),
streams,
&[
("params", StateStream::Params.whole()),
("body_states", StateStream::BodyStates.whole()),
("island_parents", RigidStream::IslandParents.whole()),
("island_state", RigidStream::IslandState.whole()),
("wake_flags", StateStream::WakeFlags.whole()),
("woke_count", dynamis_state::counter(COUNTER_WOKE)),
(
"deferred_woke_count",
dynamis_state::counter(COUNTER_WOKE_DEFERRED),
),
],
&[],
),
}
}
pub fn record(
&self,
recorder: &mut ComputeRecorder,
streams: &impl Resources,
frame: &RigidFrame,
) {
let dynamic = Count::Dynamic.rows(&frame.params);
let constraints = Count::Constraints.rows(&frame.params);
self.contact_relay.record_stream(recorder, streams);
self.contact_begin.record_stream(recorder, streams);
self.island_init.record_rows(recorder, streams, dynamic);
self.island_link_contacts.record_stream(recorder, streams);
self.island_link_constraints
.record_rows(recorder, streams, constraints);
self.island_link_resting.record_stream(recorder, streams);
for _ in 0..frame.shape.island_rounds {
self.island_jump.record_rows(recorder, streams, dynamic);
}
self.island_aggregate
.record_rows(recorder, streams, dynamic);
}
pub fn record_wake(
&self,
recorder: &mut ComputeRecorder,
streams: &impl Resources,
frame: &RigidFrame,
) {
self.island_wake
.record_rows(recorder, streams, Count::Dynamic.rows(&frame.params));
}
}
impl Sleep {
pub fn build(context: &GpuContext, streams: &impl Resources) -> Self {
Self {
island_sleep: Stage::build(
context,
"island_sleep",
rows(
context,
include_str!("../shaders/island_sleep.wgsl"),
CORE,
Count::Dynamic.field(),
),
streams,
&[
("params", StateStream::Params.whole()),
("body_states", StateStream::BodyStates.whole()),
("body_descs", StateStream::BodyDescriptors.whole()),
("island_parents", RigidStream::IslandParents.whole()),
("island_state", RigidStream::IslandState.whole()),
("wake_flags", StateStream::WakeFlags.whole()),
("slept_count", dynamis_state::counter(COUNTER_SLEPT)),
],
&[],
),
}
}
pub fn record(
&self,
recorder: &mut ComputeRecorder,
streams: &impl Resources,
frame: &RigidFrame,
) {
self.island_sleep
.record_rows(recorder, streams, Count::Dynamic.rows(&frame.params));
}
}