Fix quat3456 float array size
[dormin.git] / anb.ml
blob3d6f47c77b7060ee92fcddd8fe9665b3ce87306e
1 open Format
3 let quat0 posecount sbuf =
4 let i = Xff.rfloat sbuf 0
5 and j = Xff.rfloat sbuf 4
6 and k = Xff.rfloat sbuf 8
7 and s = Xff.rfloat sbuf 12 in
8 let q = { Qtr.i = i; j = j; k = k; s = s } in
9 Array.create posecount q
12 let expand =
13 let bits =
14 [|[|5; 9; 9; 9|]; [|9; 5; 9; 9|]; [|9; 9; 5; 9|]; [|9; 9; 9; 5|]|]
16 fun int32 typ ->
17 let toint shift mask =
18 let i = (Int32.to_int (Int32.shift_right_logical int32 shift)) land mask in
19 let i = i - ((i land ((mask + 1) lsr 1)) lsl 1) in
22 let bits = bits.(typ - 3) in
23 let shifts =
24 [| 32 - bits.(0)
25 ; 32 - bits.(0) - bits.(1)
26 ; 32 - bits.(0) - bits.(1) - bits.(2)
27 ; 0
30 let toint i = (toint shifts.(i) ((1 lsl bits.(i)) - 1)) in
31 let tofloat i = float (toint i) /. float (1 lsl (bits.(i) - 1)) in
32 let a = tofloat 0
33 and b = tofloat 1
34 and c = tofloat 2
35 and d = tofloat 3 in
36 (a, b, c, d, toint (typ - 3))
39 let quat3456 typ posecount sectbuf sbuf =
40 let floats = Array.init 8 (fun i -> Xff.rfloat sbuf (i*4)) in
41 let offset = Xff.rint sbuf 32 in
42 let sbuf32 = Xff.sbufplus sectbuf offset in
43 let int32s = Array.init posecount (fun i -> Xff.r32 sbuf32 (i*4)) in
44 let madd v n = v*.floats.(n*2 + 1) +. floats.(n*2) in
45 let omsqrt a b c mask =
46 let m = a*.a +. b*.b +. c*.c in
47 let v = if m >= 1.0 then 0.0 else sqrt (1. -. m) in
48 if mask land 0b10000 != 0 then -.v else v
50 let toquat poseno =
51 let i, j, k, s, mask = expand int32s.(poseno) typ in
52 let i, j, k, s =
53 match typ with
54 | 3 ->
55 let j = madd j 0
56 and k = madd k 1
57 and s = madd s 2 in
58 (omsqrt j k s mask, j, k, s)
59 | 4 ->
60 let i = madd i 0
61 and k = madd k 1
62 and s = madd s 2 in
63 (i, omsqrt i k s mask, k, s)
64 | 5 ->
65 let i = madd i 0
66 and j = madd j 1
67 and s = madd s 2 in
68 (i, j, omsqrt i j s mask, s)
69 | 6 ->
70 let i = madd i 0
71 and j = madd j 1
72 and k = madd k 2 in
73 (i, j, k, omsqrt i j k mask)
74 | _ -> failwith "Me fail english? That's Umpossible!"
76 { Qtr.i = i; j = j; k = k; s = s }
78 Array.init posecount toquat
81 let quat12 posecount sectbuf sbuf =
82 let floats = Array.init 6 (fun i -> Xff.rfloat sbuf (i*4)) in
83 let offset = Xff.rint sbuf 24 in
84 let sbuf16 = Xff.sbufplus sectbuf offset in
85 let madd v n =
86 float v /. 32768.0 *. floats.(n*2 + 1) +. floats.(n*2)
88 eprintf "quat12 is dead wrong@.";
89 let toquat poseno =
90 let a = Xff.r16s sbuf16 (poseno*6 + 0)
91 and b = Xff.r16s sbuf16 (poseno*6 + 2)
92 and c = Xff.r16s sbuf16 (poseno*6 + 4) in
93 let yaw = madd a 0
94 and pitch = madd b 1
95 and roll = madd c 2 in
96 (* wrong *)
97 Qtr.from_euler yaw pitch roll
99 Array.init posecount toquat
102 let quat13 posecount sectbuf sbuf =
103 let bias = Xff.rfloat sbuf 0
104 and scale = Xff.rfloat sbuf 4
105 and x = Xff.rfloat sbuf 8
106 and y = Xff.rfloat sbuf 12
107 and z = Xff.rfloat sbuf 16 in
108 let offset = Xff.rint sbuf 20 in
109 let sbuf16 = Xff.sbufplus sectbuf offset in
110 let toquat poseno =
111 let fixp = Xff.r16s sbuf16 (poseno*2) in
112 let fltp = float fixp /. 32768.0 in
113 let phi = fltp*.scale +. bias in
114 let q = Qtr.from_axis_angle x y z phi in
115 { q with Qtr.s = q.Qtr.s }
117 Array.init posecount toquat
120 let skin bones poseno =
121 let quats = Array.map (fun a -> Array.get a poseno) bones in
122 Skin.set_anim quats;
125 let r xff sbufxff =
126 if Array.length xff.Xff.sections != 2
127 then
128 Xff.sbuferr sbufxff 0 "number of xff sections is not 2"
130 let sectpos = xff.Xff.sections.(1).Xff.off in
131 let sectbuf = Xff.sbufplus sbufxff sectpos in
132 let anbbuf = Xff.sbufplus sectbuf xff.Xff.entry in
134 let bonecount = Xff.rint anbbuf 20 in
135 let boneD =
136 let off = Xff.rint anbbuf 16 in
137 Array.init bonecount (fun i -> Xff.rint sectbuf (off + i*4))
139 let boneB =
140 let off = Xff.rint anbbuf 8 in
141 Array.init bonecount (fun i -> Xff.r8 sectbuf (off + i))
143 let posecount = 0xffff land Xff.rint anbbuf 4 in
144 let rbone i =
145 let d = boneD.(i)
146 and b = boneB.(i) in
147 let sbuf = Xff.sbufplus sectbuf d in
148 match b with
149 | 0 -> quat0 posecount sbuf
150 | 3 | 4 | 5 | 6 -> quat3456 b posecount sectbuf sbuf
151 | 12 -> quat12 posecount sectbuf sbuf
152 | 13 -> quat13 posecount sectbuf sbuf
153 | _ -> failwith "Me fail english? That's Umpossible!"
155 posecount, Array.init bonecount rbone