package tiny_libs
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
From-scratch libraries for teaching: graphics, audio, compression, crypto, networking and more
Install
dune-project
Dependency
Authors
Maintainers
Sources
0.3.6.tar.gz
md5=7c636383d146d30ac6f2fa234a6253c8
sha512=c79f3823c5f8f57e5038eb640d487c61168b84aa07c61999d6622ef9fd0c890e2b03b4c6a7cdbbe9352a49e25dda00ac7bb14693cee8e3d7beeed251351a2af0
doc/src/tiny_libs.physics_3d/Hitbox3d.ml.html
Source file Hitbox3d.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120(* Claude Code * * Copyright (C) 2026 Yoann Padioleau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * (LGPL) as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. *) (* See Hitbox3d.mli *) type t = Sphere of float | Box of Vec3.t | Capsule of float * float | Plane of Vec3.t * float type placed = { shape : t; pos : Vec3.t; orientation : Quat.t } let place ?(orientation = Quat.identity) pos shape = { shape; pos; orientation } (* the local axes, turned into the world *) let axes (p : placed) : Vec3.t * Vec3.t * Vec3.t = ( Quat.rotate p.orientation (1., 0., 0.), Quat.rotate p.orientation (0., 1., 0.), Quat.rotate p.orientation (0., 0., 1.) ) let corners (p : placed) : Vec3.t list = match p.shape with | Box (hx, hy, hz) -> let ax, ay, az = axes p in List.concat_map (fun sx -> List.concat_map (fun sy -> List.map (fun sz -> Vec3.add p.pos (Vec3.add (Vec3.scale (sx *. hx) ax) (Vec3.add (Vec3.scale (sy *. hy) ay) (Vec3.scale (sz *. hz) az)))) [ -1.; 1. ]) [ -1.; 1. ]) [ -1.; 1. ] | _ -> [] let face_axes (p : placed) : Vec3.t list = match p.shape with | Box _ -> let ax, ay, az = axes p in [ ax; ay; az ] | Plane (n, _) -> [ n ] | _ -> [] let segment (p : placed) : Vec3.t * Vec3.t = match p.shape with | Capsule (half, _) -> let _, ay, _ = axes p in (Vec3.add p.pos (Vec3.scale (-.half) ay), Vec3.add p.pos (Vec3.scale half ay)) | _ -> (p.pos, p.pos) let support (p : placed) (d : Vec3.t) : Vec3.t = let u = Vec3.normalize d in match p.shape with | Sphere r -> Vec3.add p.pos (Vec3.scale r u) | Box _ -> ( match corners p with | [] -> p.pos | c :: cs -> List.fold_left (fun best q -> if Vec3.dot q u > Vec3.dot best u then q else best) c cs) | Capsule (_, r) -> let a, b = segment p in let tip = if Vec3.dot a u > Vec3.dot b u then a else b in Vec3.add tip (Vec3.scale r u) | Plane _ -> p.pos let extent (p : placed) (axis : Vec3.t) : float * float = match p.shape with | Sphere r -> let c = Vec3.dot p.pos axis in (c -. r, c +. r) | Box _ -> let ds = List.map (fun c -> Vec3.dot c axis) (corners p) in (List.fold_left Float.min infinity ds, List.fold_left Float.max neg_infinity ds) | Capsule (_, r) -> let a, b = segment p in let da = Vec3.dot a axis and db = Vec3.dot b axis in (Float.min da db -. r, Float.max da db +. r) | Plane (n, d) -> (* a half-space: everything below the plane along its normal *) if Vec3.dot n axis > 0.999999 then (neg_infinity, d) else (neg_infinity, infinity) let bounds (p : placed) : Vec3.t * Vec3.t = match p.shape with | Plane _ -> ((neg_infinity, neg_infinity, neg_infinity), (infinity, infinity, infinity)) | _ -> let along a = let lo, hi = extent p a in (lo, hi) in let lx, hx = along (1., 0., 0.) and ly, hy = along (0., 1., 0.) and lz, hz = along (0., 0., 1.) in ((lx, ly, lz), (hx, hy, hz)) let volume : t -> float = function | Sphere r -> 4. /. 3. *. Float.pi *. r *. r *. r | Box (hx, hy, hz) -> 8. *. hx *. hy *. hz | Capsule (half, r) -> (Float.pi *. r *. r *. (2. *. half)) +. (4. /. 3. *. Float.pi *. r *. r *. r) | Plane _ -> 0. let inertia ~mass : t -> Mat3.t = function | Sphere r -> Body3d.solid_sphere ~mass ~radius:r | Box (hx, hy, hz) -> Body3d.box ~mass (2. *. hx, 2. *. hy, 2. *. hz) | Plane _ -> Body3d.never_turns | Capsule (half, r) -> (* a cylinder of length 2 half and two hemispheres, each moved * onto the axis by the parallel-axis theorem: the 3 h r / 8 term * is a hemisphere's own centroid, 3r/8 from its flat face *) let l = 2. *. half in let v_cyl = Float.pi *. r *. r *. l and v_hemi = 2. /. 3. *. Float.pi *. r *. r *. r in let total = v_cyl +. (2. *. v_hemi) in let mc = mass *. v_cyl /. total and mh = mass *. v_hemi /. total in let along = (mc *. r *. r /. 2.) +. (2. *. mh *. 2. /. 5. *. r *. r) in let across = (mc *. ((l *. l /. 12.) +. (r *. r /. 4.))) +. (2. *. mh *. ((2. /. 5. *. r *. r) +. (l *. l /. 4.) +. (3. *. l *. r /. 8.))) in Mat3.diagonal across along across
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>