// Copyright 2025 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
pub struct PhysicsHooks3D {
mut filter_contact_pair : ((
@dynamics.RigidBodySet3D,
@collision.ColliderSet3D,
@collision.ColliderHandle3D,
@collision.ColliderHandle3D,
) -> Bool)?
mut filter_intersection_pair : ((
@dynamics.RigidBodySet3D,
@collision.ColliderSet3D,
@collision.ColliderHandle3D,
@collision.ColliderHandle3D,
) -> Bool)?
mut modify_solver_contacts : ((
@dynamics.RigidBodySet3D,
@collision.ColliderSet3D,
@collision.ColliderHandle3D,
@collision.ColliderHandle3D,
@core.Vec3,
) -> (Bool, @core.Vec3?))?
}
///|
fn resolve_hook_user_data_3d(
bodies : @dynamics.RigidBodySet3D,
colliders : @collision.ColliderSet3D,
collider1 : @collision.ColliderHandle3D,
collider2 : @collision.ColliderHandle3D,
) -> (
@core.UserData128,
@core.UserData128,
@dynamics.RigidBodyHandle?,
@dynamics.RigidBodyHandle?,
@core.UserData128?,
@core.UserData128?,
) {
let mut ud1 = @core.UserData128::zero()
let mut ud2 = @core.UserData128::zero()
let mut rb1 : @dynamics.RigidBodyHandle? = None
let mut rb2 : @dynamics.RigidBodyHandle? = None
let mut rb_ud1 : @core.UserData128? = None
let mut rb_ud2 : @core.UserData128? = None
if colliders.get(collider1) is Some(co1) {
ud1 = co1.user_data128()
rb1 = co1.parent()
if rb1 is Some(h1) {
if bodies.get(h1) is Some(b1) {
rb_ud1 = Some(b1.user_data128())
}
}
}
if colliders.get(collider2) is Some(co2) {
ud2 = co2.user_data128()
rb2 = co2.parent()
if rb2 is Some(h2) {
if bodies.get(h2) is Some(b2) {
rb_ud2 = Some(b2.user_data128())
}
}
}
(ud1, ud2, rb1, rb2, rb_ud1, rb_ud2)
}
///|
pub fn PhysicsHooks3D::PhysicsHooks3D() -> PhysicsHooks3D {
{
filter_contact_pair: None,
filter_intersection_pair: None,
modify_solver_contacts: None,
}
}
///|
pub fn PhysicsHooks3D::filter_contact_pair(
self : PhysicsHooks3D,
predicate : (
@dynamics.RigidBodySet3D,
@collision.ColliderSet3D,
@collision.ColliderHandle3D,
@collision.ColliderHandle3D,
) -> Bool,
) -> PhysicsHooks3D {
self.filter_contact_pair = Some(predicate)
self
}
///|
pub fn PhysicsHooks3D::filter_contact_pair_with_user_data(
self : PhysicsHooks3D,
predicate : (
@dynamics.RigidBodySet3D,
@collision.ColliderSet3D,
@collision.ColliderHandle3D,
@collision.ColliderHandle3D,
@core.UserData128,
@core.UserData128,
@dynamics.RigidBodyHandle?,
@dynamics.RigidBodyHandle?,
@core.UserData128?,
@core.UserData128?,
) -> Bool,
) -> PhysicsHooks3D {
self.filter_contact_pair = Some(fn(
bodies : @dynamics.RigidBodySet3D,
colliders : @collision.ColliderSet3D,
collider1 : @collision.ColliderHandle3D,
collider2 : @collision.ColliderHandle3D,
) -> Bool {
let (ud1, ud2, rb1, rb2, rb_ud1, rb_ud2) = resolve_hook_user_data_3d(
bodies, colliders, collider1, collider2,
)
predicate(
bodies, colliders, collider1, collider2, ud1, ud2, rb1, rb2, rb_ud1, rb_ud2,
)
})
self
}
///|
pub fn PhysicsHooks3D::filter_intersection_pair(
self : PhysicsHooks3D,
predicate : (
@dynamics.RigidBodySet3D,
@collision.ColliderSet3D,
@collision.ColliderHandle3D,
@collision.ColliderHandle3D,
) -> Bool,
) -> PhysicsHooks3D {
self.filter_intersection_pair = Some(predicate)
self
}
///|
pub fn PhysicsHooks3D::filter_intersection_pair_with_user_data(
self : PhysicsHooks3D,
predicate : (
@dynamics.RigidBodySet3D,
@collision.ColliderSet3D,
@collision.ColliderHandle3D,
@collision.ColliderHandle3D,
@core.UserData128,
@core.UserData128,
@dynamics.RigidBodyHandle?,
@dynamics.RigidBodyHandle?,
@core.UserData128?,
@core.UserData128?,
) -> Bool,
) -> PhysicsHooks3D {
self.filter_intersection_pair = Some(fn(
bodies : @dynamics.RigidBodySet3D,
colliders : @collision.ColliderSet3D,
collider1 : @collision.ColliderHandle3D,
collider2 : @collision.ColliderHandle3D,
) -> Bool {
let (ud1, ud2, rb1, rb2, rb_ud1, rb_ud2) = resolve_hook_user_data_3d(
bodies, colliders, collider1, collider2,
)
predicate(
bodies, colliders, collider1, collider2, ud1, ud2, rb1, rb2, rb_ud1, rb_ud2,
)
})
self
}
///|
pub fn PhysicsHooks3D::modify_solver_contacts(
self : PhysicsHooks3D,
callback : (
@dynamics.RigidBodySet3D,
@collision.ColliderSet3D,
@collision.ColliderHandle3D,
@collision.ColliderHandle3D,
@core.Vec3,
) -> (Bool, @core.Vec3?),
) -> PhysicsHooks3D {
self.modify_solver_contacts = Some(callback)
self
}
///|
pub fn PhysicsHooks3D::modify_solver_contacts_with_user_data(
self : PhysicsHooks3D,
callback : (
@dynamics.RigidBodySet3D,
@collision.ColliderSet3D,
@collision.ColliderHandle3D,
@collision.ColliderHandle3D,
@core.UserData128,
@core.UserData128,
@dynamics.RigidBodyHandle?,
@dynamics.RigidBodyHandle?,
@core.UserData128?,
@core.UserData128?,
@core.Vec3,
) -> (Bool, @core.Vec3?),
) -> PhysicsHooks3D {
self.modify_solver_contacts = Some(fn(
bodies : @dynamics.RigidBodySet3D,
colliders : @collision.ColliderSet3D,
collider1 : @collision.ColliderHandle3D,
collider2 : @collision.ColliderHandle3D,
normal : @core.Vec3,
) -> (Bool, @core.Vec3?) {
let (ud1, ud2, rb1, rb2, rb_ud1, rb_ud2) = resolve_hook_user_data_3d(
bodies, colliders, collider1, collider2,
)
callback(
bodies, colliders, collider1, collider2, ud1, ud2, rb1, rb2, rb_ud1, rb_ud2,
normal,
)
})
self
}
///|
fn PhysicsHooks3D::test_contact_pair(
self : PhysicsHooks3D,
bodies : @dynamics.RigidBodySet3D,
colliders : @collision.ColliderSet3D,
collider1 : @collision.ColliderHandle3D,
collider2 : @collision.ColliderHandle3D,
) -> Bool {
if self.filter_contact_pair is Some(predicate) {
predicate(bodies, colliders, collider1, collider2)
} else {
true
}
}
///|
fn PhysicsHooks3D::test_intersection_pair(
self : PhysicsHooks3D,
bodies : @dynamics.RigidBodySet3D,
colliders : @collision.ColliderSet3D,
collider1 : @collision.ColliderHandle3D,
collider2 : @collision.ColliderHandle3D,
) -> Bool {
if self.filter_intersection_pair is Some(predicate) {
predicate(bodies, colliders, collider1, collider2)
} else {
true
}
}
///|
fn PhysicsHooks3D::modify_solver_contacts_internal(
self : PhysicsHooks3D,
bodies : @dynamics.RigidBodySet3D,
colliders : @collision.ColliderSet3D,
collider1 : @collision.ColliderHandle3D,
collider2 : @collision.ColliderHandle3D,
normal : @core.Vec3,
) -> (Bool, @core.Vec3?) {
if self.modify_solver_contacts is Some(callback) {
callback(bodies, colliders, collider1, collider2, normal)
} else {
(true, None)
}
}