Color material support and misc refactoring
[dormin.git] / skb.ml
blob2a0ccfa3fe00d36dbed8ccb2739280396c533be0
1 open Format;;
3 let qof f = Qtr.make f.(5) f.(6) f.(7) f.(8);;
4 let vof f = Vec.make f.(1) f.(2) f.(3);;
6 type t = int * (string * int32 array * float array * int array * float);;
8 let rt sbuf strtab =
9 let d = Array.init 3 (fun n -> Xff.r32 sbuf (n*4)) in
10 let f9 = Array.init 9 (fun n -> Xff.rfloat sbuf (12 +n*4)) in
11 let h = Array.init 3 (fun n -> Xff.rint sbuf (48 + n*4)) in
12 let f = Xff.rfloat sbuf 60 in
13 (Xff.rcstrtabent strtab 0 (Int32.to_int d.(0)), d, f9, h, f)
16 let r1 xff sbufxff =
17 if Array.length xff.Xff.sections != 2
18 then
19 Xff.sbuferr sbufxff 0 "number of xff sections is not 2"
21 let sectpos = xff.Xff.sections.(1).Xff.off in
22 let sectbuf = Xff.sbufplus sbufxff sectpos in
23 let skbbuf = Xff.sbufplus sectbuf xff.Xff.entry in
25 let count1 = Xff.rint skbbuf 4 in
26 let _pos1 = Xff.rint skbbuf 8 in
27 let tabpos1 = Xff.rint skbbuf 12 in
28 let strtab1 = Xff.sbufplus sectbuf tabpos1 in
30 let bones = Array.init count1 (fun n ->
31 let pos = Xff.rint skbbuf (44 + n*8) in
32 let sbuf = Xff.sbufplus sectbuf pos in
33 pos + sectpos, rt sbuf strtab1)
35 bones
38 let vertices bones =
39 let parentinfo = Array.make (Array.length bones + 1) (Qtr.id, Vec.origin) in
40 let mapf i (_pos, (_name, _offsets, floats, neighbors, _float)) =
41 let curq = qof floats in
42 let curv = vof floats in
44 let parent = neighbors.(2) in
45 let parentq, parentv = parentinfo.(parent + 1) in
47 let v = Qtr.apply parentq curv in
48 let v = Vec.add v parentv in
50 let q = Qtr.compose curq parentq in
51 parentinfo.(i + 1) <- (q, v);
52 Vec.elts parentv, Vec.elts v;
54 Array.mapi mapf bones;
57 let vertices1 bones rotations poseno =
58 let parentinfo = Array.make (Array.length bones + 1) (Qtr.id, Vec.origin) in
59 let mapf i (pos, (name, offsets, floats, neighbors, float)) =
60 let curq = rotations.(i).(poseno) in
61 let curv = vof floats in
63 let parent = neighbors.(2) in
64 let parentq, parentv = parentinfo.(parent + 1) in
66 let v = Qtr.apply parentq curv in
67 let v = Vec.add v parentv in
69 let q = Qtr.compose curq parentq in
70 parentinfo.(i + 1) <- (q, v);
71 Vec.elts parentv, Vec.elts v;
73 Array.mapi mapf bones;
76 let draw data =
77 let rta = vertices data in
79 let sphere origin =
80 GlMat.mode `modelview;
81 GlMat.push ();
82 GlMat.translate3 (origin);
83 let radius = Rend.view.Rend.radial_scale*.0.009 in
84 GluQuadric.sphere ~radius ~stacks:5 ~slices:5 ();
85 GlMat.pop ()
88 fun () ->
89 GlDraw.polygon_mode `both `line;
90 Gl.disable `depth_test;
91 Array.iteri
92 (fun i (pos, (n, d, m, h, f)) ->
93 GlDraw.line_width 0.1;
94 GlDraw.color (0., 0., 1.);
95 let v0, v1 = rta.(i) in
96 sphere v1;
97 GlDraw.line_width 2.0;
98 GlDraw.begins `lines;
99 GlDraw.vertex3 v0;
100 GlDraw.vertex3 v1;
101 GlDraw.ends ();
102 ) data;
103 Gl.enable `depth_test;
106 let draw1 bones =
107 fun rotations poseno ->
108 let rta = vertices1 bones rotations poseno in
109 fun () ->
110 GlDraw.polygon_mode `both `line;
111 GlDraw.color (0., 0., 1.);
112 Gl.disable `depth_test;
113 for i = 0 to Array.length bones - 1 do
114 (* GlDraw.line_width 0.1; *)
115 let v0, v1 = rta.(i) in
116 (* sphere v1; *)
117 GlDraw.line_width 2.0;
118 GlDraw.begins `lines;
119 GlDraw.vertex3 v0;
120 GlDraw.vertex3 v1;
121 GlDraw.ends ();
122 done;
123 Gl.enable `depth_test;
126 let func bones anim =
127 let posecount, rotations = anim in
128 let draw0 = draw bones in
129 let draw1 = draw1 bones in
130 let rec subfunc dodraw poseno draw = function
131 | Rend.Char ('f'|'b' as c) ->
132 let poseno =
133 if c = 'b' then
134 let poseno = if poseno = 0 then posecount else poseno in
135 (poseno - 1) mod posecount
136 else
137 (poseno + 1) mod posecount
139 let draw = draw1 rotations poseno in
140 Anb.skin rotations poseno;
141 Skin.anim ();
142 Rend.Func (subfunc dodraw poseno draw)
143 | Rend.Char 'r' ->
144 Rend.Func (subfunc dodraw 0 draw0)
145 | Rend.Draw ->
146 if dodraw then draw ();
147 Rend.Func (subfunc dodraw poseno draw)
148 | Rend.Char 's' -> Rend.Func (subfunc (not dodraw) poseno draw)
149 | Rend.Char _ -> Rend.Func (subfunc dodraw poseno draw)
151 subfunc false 0 (draw bones)
154 let dummy draw =
155 let rec subfunc dodraw = function
156 | Rend.Draw -> if dodraw then draw (); Rend.Func (subfunc dodraw)
157 | Rend.Char 's' -> Rend.Func (subfunc (not dodraw))
158 | _ -> Rend.Func (subfunc dodraw)
160 subfunc false
163 let skin bones =
164 let skel = Array.map
165 (fun (_, (_, _, floats, neighbors, _)) -> (neighbors.(2), floats))
166 bones
168 Skin.set_skel skel;
171 let main name =
172 let func =
174 let name = Filename.chop_extension name ^ ".skb" in
175 let xff, sbuf = Xff.test2 name in
176 let bones = r1 xff sbuf in
177 begin try
178 let anim_name =
179 match !Rend.anb_name with
180 | None -> raise (Failure "no animation set")
181 | Some name ->name
183 let xff, sbuf = Xff.test2 (Filename.basename anim_name) in
184 let anim = Anb.r xff sbuf in
185 skin bones;
186 func bones anim
187 with exn ->
188 prerr_endline (Printexc.to_string exn);
189 dummy (draw bones)
190 end;
191 with exn ->
192 prerr_endline (Printexc.to_string exn);
193 dummy (fun () -> ())
195 Rend.add_func func