open GlDraw
let rx = ref 0.
let ry = ref (-.70.)
let tx = ref 0.
let ty = ref 0.
let tz = ref (-.4.)
let cam_transfo () =
GlMat.translate3 (!tx, !ty, !tz) ;
GlMat.rotate ~angle:!rx ~x:1. ~y:0. ~z:0. () ;
GlMat.rotate ~angle:!ry ~x:0. ~y:1. ~z:0. ()
let lx = ref 1.
let ly = ref 1.
let lz = ref 1.
let lstep = 0.5
let grid_step = ref 0.18
let walk = ref true
let usage = "skeg [options] file"
let _ =
Printf.printf "%s %s\n\n"
("Skeg 0.1.0 - Sex, Kinematics, Elegance and Glory.\n\n"^
"Copyright (C) 2004 David Baelde and Samuel Mimram.\n"^
"Compiled with OCaml") Sys.ocaml_version ;
Arg.parse_argv (Glut.init Sys.argv)
[
"-W", Arg.Clear walk, "Walk mode"
]
(fun s -> ()) usage;
module Walk =
struct
let skel =
[| [| false ; false ; true ; false |] ;
[| false ; false ; true ; false |] ;
[| true ; true ; false ; true |] ;
[| false ; false ; true ; false |] |]
let pos = [| -1.,0.,-0.5 ; 1.,0.,0. ; 0.,1.,0. ; 0.,2.,0.|]
let root = 1
let all = skel, pos, root
let first = 0
end
module P =
struct
let skel,pos,root =
if !walk then
Walk.all
else
Ik.TestLongY.all
end
module A = Ik.Acyclic(P)
module Solver = Ik.Gauss (struct let epsilon = 0.05 end) (A)
let selected =
ref (if !walk then 1-Walk.first else 0)
let display () =
GlClear.clear [`color; `depth] ;
GlMat.push ();
cam_transfo () ;
GlLight.light 0 (`position (!lx, !ly, !lz, 1.)) ;
GlLight.material ~face:`both (`specular (1., 1., 1., 1.0)) ;
GlLight.material ~face:`both (`diffuse (0., 0.5, 0., 1.0)) ;
GlLight.material ~face:`both (`shininess 100.) ;
if !walk then begin
begins `lines ;
GlLight.material ~face:`both (`ambient (0.,1.,0.,1.)) ;
vertex3 (-1.,0.,-1000.) ;
vertex3 (-1.,0.,1000.) ;
GlLight.material ~face:`both (`ambient (1.,0.,0.,1.)) ;
vertex3 (1.,0.,-1000.) ;
vertex3 (1.,0.,1000.) ;
GlLight.material ~face:`both (`ambient (1.,1.,1.,1.)) ;
vertex3 (1.,0.,0.) ;
vertex3 (-1.,0.,0.) ;
vertex3 (-1.,0.,0.) ;
vertex3 (0.,0.,0.8) ;
vertex3 (0.,0.,0.8) ;
vertex3 (1.,0.,0.) ;
ends ()
end ;
GlLight.material ~face:`both (`ambient (0.6, 0.6, 0.6, 1.0)) ;
if !walk then
Visu.visu_mb 10. (Array.mapi (fun i (x, y, z) ->
(x, y, z, if i = 2 then 5. else 1.))
Solver.pos)
else
Visu.visu_mb 10. (Array.map (fun (x, y, z) -> (x, y, z, 1.)) Solver.pos) ;
GlMat.pop () ;
Glut.swapBuffers ()
let on_key ~key:k ~x:x ~y:y =
( match k with
| Glut.KEY_PAGE_UP -> tz := !tz +. 0.1
| Glut.KEY_PAGE_DOWN -> tz := !tz -. 0.1
| Glut.KEY_UP -> rx := !rx +. 10.
| Glut.KEY_DOWN -> rx := !rx -. 10.
| Glut.KEY_LEFT -> ry := !ry +. 10.
| Glut.KEY_RIGHT -> ry := !ry -. 10.
| _ -> ()
) ;
Glut.postRedisplay ()
let do_move move =
if !A.root <> !selected then
( Solver.begin_move ~steps:1 move ;
Glut.idleFunc
(Some (fun () ->
if Solver.move () then
Glut.idleFunc None ;
Glut.postRedisplay ())) )
else
Printf.printf "Can't move the root !%!\n"
let walk_step () =
A.init !selected ;
selected := 1 - !selected ;
let move = Array.make (3*(Array.length Walk.skel)) None in
move.(0+3* !selected) <- Some 0. ;
move.(1+3* !selected) <- Some 0. ;
move.(2+3* !selected) <- Some 1. ;
Solver.begin_move_precise ~steps:(-1) move ;
Glut.idleFunc
(Some (fun () ->
if Solver.move () then
begin
let (x,y,z) = Solver.pos.(!selected) in
let xgoal = if !selected = 1 then 1. else -1. in
move.(0+3* !selected) <- Some (xgoal-.x) ;
move.(1+3* !selected) <- Some (0.-.y) ;
move.(2+3* !selected) <- Some (0.) ;
move.(2+3*3) <- Some 0.5 ;
Solver.begin_move_precise ~steps:(-1) move ;
Glut.idleFunc
(Some (fun () ->
if Solver.move () then
Glut.idleFunc None
else
Glut.postRedisplay ()))
end
else
Glut.postRedisplay ()))
let on_kbd ~key:k ~x:x ~y:y =
( match k with
| 113
| 27 -> exit 0
| 105 -> lx := !lx +. lstep ; Glut.postRedisplay ()
| 107 -> lx := !lx -. lstep ; Glut.postRedisplay ()
| 111 -> ly := !ly +. lstep ; Glut.postRedisplay ()
| 108 -> ly := !ly -. lstep ; Glut.postRedisplay ()
| 112 -> lz := !lz +. lstep ; Glut.postRedisplay ()
| 109 -> lz := !lz -. lstep ; Glut.postRedisplay ()
| 115 ->
grid_step := !grid_step +. 0.01; Visu.set_step_mb !grid_step ;
Glut.postRedisplay ()
| 122 ->
grid_step := !grid_step -. 0.01; Visu.set_step_mb !grid_step ;
Glut.postRedisplay ()
| 32 when !walk -> walk_step ()
| _ -> Printf.printf "Unknown key pressed: %d\n%!" k )
let on_mouse ~button:btn ~state:state ~x:x ~y:y =
if btn = Glut.LEFT_BUTTON && state = Glut.DOWN then
let x, y =
float_of_int x, float_of_int ((Glut.get Glut.WINDOW_WIDTH) - y - 1)
in
let p0, p1 =
GlMat.push ();
cam_transfo () ;
let p0, p1 =
GluMat.unproject (x, y, 0.),
GluMat.unproject (x, y, 1.) in
GlMat.pop (); p0, p1
in
let pv = Vect.normalize (Vect.sub p1 p0) in
selected :=
(
let mi = ref (-1) in
let md = ref infinity in
for i = 0 to ((Array.length Solver.pos) - 1)
do
let md' = Vect.dist_from_point p0 pv Solver.pos.(i) in
if md' < !md then
(
mi := i;
md := md'
)
done; !mi
) ;
let sx, sy, sz = Solver.pos.(!selected) in
let zv = Vect.proj3 pv in
let nx, ny, nz =
Vect.add p0 (Vect.mult pv ((sz -. (Vect.proj3 p0)) /. zv))
in
let move = Skel.Constraints.empty (Array.length Solver.skel.(0)) in
move.(!selected) <- Some (nx -. sx, ny -. sy, nz -. sz);
Printf.printf "moving %d from %f %f %f to %f %f %f\n%!"
!selected sx sy sz nx ny nz;
do_move move
let init_display () =
Glut.initDisplayMode ~double_buffer:true ~depth:true ();
Glut.initWindowSize 500 500;
ignore (Glut.createWindow "Skeg - Sex, Kinematics, Elegance and Glory");
GlClear.color (0., 0., 0.);
shade_model `smooth ;
GlLight.light_model (`two_side true) ;
GlLight.light 0 (`ambient (0.5,0.,0.,1.)) ;
GlLight.light 0 (`diffuse (0.,0.7,0.,1.)) ;
GlLight.light 0 (`specular (0.,0.,0.7,1.)) ;
List.iter Gl.enable
[`depth_test;`lighting;`light0;`normalize] ;
Glut.specialFunc on_key ;
Glut.keyboardFunc on_kbd ;
Glut.displayFunc display ;
if not !walk then Glut.mouseFunc on_mouse ;
Glut.reshapeFunc (fun ~w:x ~h:y -> Glut.postRedisplay ()) ;
GlMat.mode `projection ;
GlMat.load_identity () ;
GluMat.perspective ~fovy:80. ~aspect:1. ~z:(0.1,100.);
Visu.set_step_mb !grid_step
let i_help =
"Click to move a vertex."
let w_help =
"Use <space> to make mrblob have a step."
let () =
init_display () ;
Printf.printf "%s%!"
("\n"^(if !walk then w_help else i_help)^"\n"^
"Use <escape> or 'q' to exit, arrows to move the camera.\n"^
"Use 'i'/'k', 'o'/'l' and 'p'/'m' to move the light,\n"^
"and 'z'/'s' to change the metaballs smoothness.\n"^
"Please don't report bugs :)\n\n") ;
Glut.mainLoop ()