// 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.
///|
/// Source-aligned dim3 collider builder alias.
pub type ColliderBuilder3 = ColliderBuilder3D
///|
/// Source-aligned dim3 compatibility alias.
/// This intentionally resolves to the real dim3 builder implementation.
pub type ColliderBuilder3Compat = ColliderBuilder3D
///|
pub fn Collider::translation3(self : Collider) -> @core.Vec3 {
let t = self.translation()
Vec3(t.x, t.y, 0.0F)
}
///|
fn recompute_body_mass_properties_from_attached_colliders3(
bodies : @dynamics.RigidBodySet3,
colliders : ColliderSet3,
body_handle : @dynamics.RigidBodyHandle,
) -> Unit {
if bodies.get_mut(body_handle) is Some(body) {
let attached = colliders.colliders_with_parent(body_handle)
let mut mprops = @core.MassProperties::default()
for j in 0.. ignore
body.set_local_mass_properties(mprops) |> ignore
body.recompute_mass_properties_from_colliders() |> ignore
}
}
///|
fn ColliderSet3::sync_with_bodies(
self : ColliderSet3,
bodies : @dynamics.RigidBodySet3,
) -> Unit {
for i in 0.. ColliderSet3 {
{ inner: ColliderSet() }
}
///|
pub fn ColliderSet3::as_2d(self : ColliderSet3) -> ColliderSet {
self.inner
}
///|
pub fn ColliderSet3::len(self : ColliderSet3) -> Int {
self.inner.len()
}
///|
pub fn ColliderSet3::insert(
self : ColliderSet3,
collider : Collider,
) -> ColliderHandle {
self.inner.insert(collider)
}
///|
pub fn ColliderSet3::insert_with_parent(
self : ColliderSet3,
collider : Collider,
parent : @dynamics.RigidBodyHandle,
bodies : @dynamics.RigidBodySet3,
) -> ColliderHandle {
let handle = self.inner.allocate_handle()
let updated = collider
updated.changes = ColliderChanges::all()
updated.parent = Some(parent)
if bodies.get(parent) is Some(body) {
let body_pos = body.position()
let local_pos = @core.Isometry2(
updated.local_translation,
@core.Rot2::from_angle(updated.local_rotation),
)
let world_pos = body_pos.mul(local_pos)
updated.world_translation = world_pos.translation
updated.world_rotation = world_pos.rotation.angle()
} else {
updated.world_translation = updated.local_translation
updated.world_rotation = updated.local_rotation
}
self.inner.colliders[handle.id] = Some(updated)
if self.inner.colliders[handle.id] is Some(collider_ref) {
self.inner.push_modified_unchecked(handle, collider_ref)
}
if bodies.get_mut(parent) is Some(body) {
let (collider_id, collider_generation) = handle.into_raw_parts()
body.attach_collider_raw(collider_id, collider_generation) |> ignore
}
recompute_body_mass_properties_from_attached_colliders3(bodies, self, parent)
handle
}
///|
pub fn ColliderSet3::remove(
self : ColliderSet3,
handle : ColliderHandle,
islands : @dynamics.IslandManager3,
bodies : @dynamics.RigidBodySet3,
wake_up : Bool,
) -> Unit {
if handle.id < 0 || handle.id >= self.inner.colliders.length() {
return
}
if self.inner.generations[handle.id] != handle.generation {
return
}
if self.inner.colliders[handle.id] is Some(collider) {
let parent = collider.parent
let (collider_id, collider_generation) = handle.into_raw_parts()
if parent is Some(parent_handle) {
if bodies.get_mut(parent_handle) is Some(body) {
body.detach_collider_raw(collider_id, collider_generation) |> ignore
body.mark_local_mass_properties_changed() |> ignore
if wake_up && body.is_dynamic_or_kinematic() {
body.wake_up(true) |> ignore
}
}
}
self.inner.colliders[handle.id] = None
self.inner.removed_colliders.push(handle)
self.inner.generations[handle.id] = self.inner.generations[handle.id] + 1
self.inner.free_list.push(handle.id)
if parent is Some(parent_handle) {
recompute_body_mass_properties_from_attached_colliders3(
bodies, self, parent_handle,
)
if wake_up {
islands.wake_up(bodies, parent_handle, true)
}
}
}
}
///|
pub fn ColliderSet3::colliders_with_parent(
self : ColliderSet3,
parent : @dynamics.RigidBodyHandle,
) -> Array[ColliderHandle] {
self.inner.colliders_with_parent(parent)
}
///|
pub fn ColliderSet3::get(
self : ColliderSet3,
handle : ColliderHandle,
) -> Collider? {
self.inner.get(handle)
}
///|
pub fn ColliderSet3::set_parent(
self : ColliderSet3,
handle : ColliderHandle,
parent : @dynamics.RigidBodyHandle?,
bodies : @dynamics.RigidBodySet3,
) -> Unit {
if self.inner.get_mut_internal_with_modification_tracking(handle)
is Some(collider) {
let old_parent = collider.parent
let (collider_id, collider_generation) = handle.into_raw_parts()
collider.parent = parent
collider.changes = collider.changes.insert(COLLIDER_CHANGES_PARENT)
if old_parent is Some(old_parent_handle) {
if bodies.get_mut(old_parent_handle) is Some(body) {
body.detach_collider_raw(collider_id, collider_generation) |> ignore
}
}
if parent is Some(parent_handle) {
if bodies.get_mut(parent_handle) is Some(body) {
body.attach_collider_raw(collider_id, collider_generation) |> ignore
}
if bodies.get(parent_handle) is Some(body) {
let body_pos = body.position()
let local_pos = @core.Isometry2(
collider.local_translation,
@core.Rot2::from_angle(collider.local_rotation),
)
let world_pos = body_pos.mul(local_pos)
collider.world_translation = world_pos.translation
collider.world_rotation = world_pos.rotation.angle()
} else {
collider.world_translation = collider.local_translation
collider.world_rotation = collider.local_rotation
}
recompute_body_mass_properties_from_attached_colliders3(
bodies, self, parent_handle,
)
} else {
collider.world_translation = collider.local_translation
collider.world_rotation = collider.local_rotation
}
if old_parent is Some(old_parent_handle) {
recompute_body_mass_properties_from_attached_colliders3(
bodies, self, old_parent_handle,
)
}
}
}
///|
pub fn ColliderSet3::take_modified(
self : ColliderSet3,
) -> Array[ColliderHandle] {
self.inner.take_modified()
}
///|
pub fn ColliderSet3::set_parent_enabled(
self : ColliderSet3,
handle : @dynamics.RigidBodyHandle,
enabled : Bool,
) -> Unit {
self.inner.set_parent_enabled(handle, enabled)
}
///|
pub fn ColliderSet3::clear_changes_for(
self : ColliderSet3,
modified_colliders : Array[ColliderHandle],
) -> Unit {
self.inner.clear_changes_for(modified_colliders)
}