23 |
|
|
24 |
package gzz.modules.pp.vob; |
package gzz.modules.pp.vob; |
25 |
|
|
26 |
|
import java.lang.Math; |
27 |
|
|
28 |
import gzz.vob.*; |
import gzz.vob.*; |
29 |
import gzz.gfx.gl.*; |
import gzz.gfx.gl.*; |
30 |
|
|
31 |
|
/** Coordsystem generator prototype |
32 |
|
* -used in pp. |
33 |
|
*/ |
34 |
public class VobCSGenerator { |
public class VobCSGenerator { |
35 |
public static final String rcsid = "$Id$"; |
public static final String rcsid = "$Id$"; |
36 |
static public boolean dbg=false; |
static public boolean dbg=false; |
40 |
static public final int HORIZONTAL = 1; |
static public final int HORIZONTAL = 1; |
41 |
static public final int VERTICAL = 2; |
static public final int VERTICAL = 2; |
42 |
|
|
43 |
public float biggest_percent = 0.5f; |
private int mode = HORIZONTAL; |
|
public float percent_of_predecessor = 0.7f; |
|
|
public float smallest_percent = 0.2f; |
|
44 |
|
|
45 |
|
static public float small_area = 2.0f/5.0f; |
46 |
|
static public float noFocus_biggest_percent = 0.72f; |
47 |
|
static public float biggest_percent = 0.69f; |
48 |
|
static public float percent_of_predecessor = 0.72f; |
49 |
|
static public float smallest_percent = 0.4f; |
50 |
|
|
|
private int vob_cs[]; |
|
51 |
|
|
52 |
|
private int vob_cs[]; |
53 |
|
private boolean noFocus; |
54 |
|
|
55 |
|
|
56 |
/** @params |
/** Generates coordsystems |
57 |
* focus_index begins from 0 |
* @param vs current VobScene. |
58 |
* or -1 if focus in home paper. |
* @param cs_into (orthoCS). |
59 |
|
* @param vob_count count of vobs. |
60 |
|
* @param focus_index begins from 0 or -1 if no focus. |
61 |
|
* @param vob_width 1:1 size of biggest vob. |
62 |
|
* @param vob_height 1:1 size of biggest vob. |
63 |
*/ |
*/ |
64 |
public VobCSGenerator(VobScene vs, int cs_into, int vob_count, |
public VobCSGenerator(VobScene vs, int cs_into, int vob_count, |
65 |
int focus_index, float vob_width, float vob_height) { |
int focus_index, float vob_width, float vob_height) { |
66 |
|
|
67 |
if (dbg) pa("Vobs: "+ vob_count+" focus on: "+ focus_index); |
if (dbg) pa("Vobs: "+ vob_count+" focus on: "+ focus_index); |
68 |
if ( vob_count == 0) { |
if (vob_count <= 0) { |
69 |
pa("DEBUG: Might be an error - but there are no vob around!"); |
pa("DEBUG: Might be an error - but there are no vob around!"); |
70 |
return; |
return; |
71 |
} |
} |
72 |
|
|
73 |
|
// check: -1 is exception |
74 |
|
if (focus_index == -1) { |
75 |
|
focus_index++; |
76 |
|
noFocus = true; |
77 |
|
} else noFocus = false; |
78 |
|
|
|
// check out.. -1 is exception |
|
|
if (focus_index == -1) focus_index++; |
|
79 |
if ( 0 <= focus_index && focus_index < vob_count); |
if ( 0 <= focus_index && focus_index < vob_count); |
80 |
else throw new Error("Focus out of vobs"); |
else throw new Error("Focus out of vobs"); |
81 |
|
VobCoorder glc = vs.coords; |
|
GLVobCoorder glc = (GLVobCoorder)vs.coords; |
|
82 |
|
|
83 |
// count how long the width is in given cs |
// count how long the width is in given cs |
84 |
float [] coords = { 0,0,0, 1,1,0 }; |
float [] coords = { 0,0,0, 1,1,0 }; |
87 |
glc.transformPoints3(cs_into, coords, trans); |
glc.transformPoints3(cs_into, coords, trans); |
88 |
float x_diff = trans[3] - trans[0]; |
float x_diff = trans[3] - trans[0]; |
89 |
float y_diff = trans[4] - trans[1]; |
float y_diff = trans[4] - trans[1]; |
90 |
|
if (dbg) pa("x: "+x_diff+" y: "+y_diff); |
|
|
|
|
|
|
|
|
|
|
final int fake_count = 2 + vob_count; |
|
|
final int fake_focus = focus_index + 2; |
|
|
|
|
91 |
|
|
92 |
float spare_space = y_diff/vob_height - 1; |
float spare_space = y_diff/vob_height - 1; |
93 |
pa("spare: " + spare_space); |
if (dbg) pa("spare: " + spare_space); |
94 |
|
vob_cs = new int[vob_count]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float [] rations = new float[vob_count]; |
|
|
//float[] sigs = countSigmund(fake_focus); |
|
|
|
|
|
float[] sigs = countBoxAlgorithm(fake_focus/fake_count * spare_space, |
|
|
fake_focus, vob_height); |
|
|
|
|
95 |
|
|
|
for (int i=focus_index; i>=0; i--) { |
|
|
rations[i] = sigs[focus_index-i]; |
|
|
} |
|
96 |
|
|
97 |
//sigs = countSigmund(fake_count - fake_focus); |
/* If so few vobs that they fit well in given space. Fill it 100% |
98 |
sigs = countBoxAlgorithm((fake_count - fake_focus)/fake_count * spare_space, |
*/ |
99 |
fake_count-fake_focus, vob_height); |
if (vob_count <= spare_space + 1) { |
100 |
for (int i=focus_index; i<vob_count; i++) { |
for(int i=0; i<spare_space+1 && i<vob_count; i++) { |
101 |
rations[i] = sigs[Math.abs(focus_index - i)]; |
float y = trans[1] + .9f * i * vob_height + 0.5f*vob_height; |
102 |
|
if (dbg) pa(i+" Y: "+y); |
103 |
|
|
104 |
|
int a_cs = ((GLVobCoorder)vs.coords).affineCoordsys(0, 100, trans[0]+x_diff/2, y, |
105 |
|
1,0,0,1); |
106 |
|
vob_cs[i] = vs.orthoBoxCS(a_cs, "frame"+i, 100, -vob_width/2, -vob_height/2, |
107 |
|
1,1, vob_width,vob_height); |
108 |
|
vs.matcher.add(a_cs, "ctr"+i); |
109 |
|
} |
110 |
|
return; |
111 |
} |
} |
112 |
|
|
|
//for (int i=0; i<vob_count; i++) { p("["+rations[i]+"],");} |
|
|
|
|
|
|
|
113 |
|
|
114 |
// focus is number ONE(the biggest) - "Uuno on numero yksi..." =) |
/* Count rations |
115 |
rations[focus_index] = 1.0f; |
*/ |
116 |
//proportion(rations, focus_index, y_diff/vob_height ); |
float [] rations = new float[vob_count]; |
117 |
|
if (noFocus) { |
118 |
|
rations = countBoxAlgorithm(vob_count, spare_space + 1); |
119 |
|
} else { |
120 |
|
float hi = (vob_count - (float)focus_index-1)/vob_count * spare_space; |
121 |
|
float lo = (float)focus_index/vob_count * spare_space; |
122 |
|
// pa("hi "+hi+", low"+lo+" area "+(small_area*spare_space)); |
123 |
|
if (lo < small_area * spare_space && focus_index != 0 || |
124 |
|
hi < small_area * spare_space && focus_index+1 != vob_count) { |
125 |
|
hi = spare_space/2; |
126 |
|
lo = spare_space/2; |
127 |
|
} |
128 |
|
|
129 |
for (int i=0; i<vob_count; i++) { |
float [] low = countBoxAlgorithm(focus_index, lo); |
130 |
if (dbg) p("["+rations[i]+"],"); |
int j=0; |
131 |
|
for (int i=low.length-1; i>=0; i--) { |
132 |
|
rations[j++] = low[i]; |
133 |
|
} |
134 |
|
float [] high = countBoxAlgorithm(vob_count-focus_index-1, hi); |
135 |
|
for (int i=0; i<high.length; i++) { |
136 |
|
rations[focus_index + i +1] = high[i]; |
137 |
|
} |
138 |
|
// focus is number ONE(the biggest) - "Uuno on numero yksi..." =) |
139 |
|
rations[focus_index] = 1; |
140 |
} |
} |
141 |
|
|
142 |
float sum = 0; |
if (dbg) { |
143 |
for (int i=0; i<rations.length; i++) { |
pa("******FINAL"); |
144 |
sum += rations[i]; |
for (int i=0; i<rations.length; i++) { p("["+rations[i]+"],");} |
145 |
|
pa("\nFINAL******"); |
146 |
} |
} |
147 |
|
|
|
vob_cs = new int[vob_count]; |
|
|
|
|
|
float real_ratio = y_diff/sum; |
|
|
|
|
148 |
float x_center = trans[0] + x_diff/2; |
float x_center = trans[0] + x_diff/2; |
149 |
float y_tmp = trans[1]; |
float summ = 0; |
|
|
|
|
float vob_x0 = x_center - vob_width/2; |
|
|
|
|
150 |
for (int i=0; i<vob_count; i++) { |
for (int i=0; i<vob_count; i++) { |
151 |
float muutos = rations[i] * real_ratio; |
float y_center = trans[1] + summ + vob_height * rations[i]/2; |
152 |
float y = muutos + y_tmp; |
float yd = vob_height * rations[i]; |
153 |
|
int ctr = |
154 |
float y_d = y - y_tmp; |
((GLVobCoorder)vs.coords).affineCoordsys(0, 100, x_center, y_center, |
155 |
|
1,0,0,1); |
|
int ctr = ((GLVobCoorder)vs.coords).affineCoordsys(0, 100, |
|
|
x_center, y_tmp + muutos/2, |
|
|
1, 0, 0, 1); |
|
156 |
vs.matcher.add(ctr, "ctrl"+i); |
vs.matcher.add(ctr, "ctrl"+i); |
|
|
|
157 |
vob_cs[i] = vs.orthoBoxCS(ctr, "frame", 100, |
vob_cs[i] = vs.orthoBoxCS(ctr, "frame", 100, |
158 |
-vob_width/2, -y_d/2, 1,1, |
-vob_width/2, -yd/2, 1,1, |
159 |
vob_width, y_d); |
vob_width, yd); |
160 |
|
summ += vob_height * rations[i]; |
|
if (dbg) { |
|
|
if (i == focus_index) pa("y_tmp: "+ y_tmp +" y_cent: " +(y-muutos/2) + |
|
|
" y: "+y +" koko: "+(y-y_tmp)+ " FOCUS"); |
|
|
else pa("y_tmp: "+ y_tmp +" y_cent: " +(y-muutos/2) +" y: "+y +" koko: "+(y-y_tmp)); |
|
|
} |
|
|
|
|
|
y_tmp = y; |
|
161 |
} |
} |
162 |
} |
} |
163 |
|
|
167 |
*/ |
*/ |
168 |
public int getNextCS() { |
public int getNextCS() { |
169 |
int i = index; |
int i = index; |
170 |
if (i < 0 || i >= vob_cs.length) throw new Error("index: "+index+ " out of vob_cs.length"); |
if (i < 0 || i >= vob_cs.length) |
171 |
|
throw new Error("index: "+index+ " out of vob_cs.length"); |
172 |
return vob_cs[index++]; |
return vob_cs[index++]; |
173 |
} |
} |
174 |
|
|
175 |
/** Easy algorithm |
/** Easy algorithm |
176 |
*/ |
*/ |
177 |
private float[] countBoxAlgorithm(float f, int count, float length) { |
private float[] countBoxAlgorithm(int count, float length) { |
178 |
|
if (dbg) pa("count:"+count+" length:"+length); |
179 |
if (count <= 1) return new float[]{ biggest_percent }; |
if (count == 0) return new float[]{}; |
180 |
|
if (count == 1) { |
181 |
// first index is fake or smthng.. |
if (noFocus) return new float[]{ biggest_percent * percent_of_predecessor}; |
182 |
|
else return new float[]{ biggest_percent}; |
183 |
|
} |
184 |
|
|
185 |
float[] retArray = new float[count]; |
float[] retArray = new float[count]; |
|
retArray[1] = biggest_percent; |
|
|
|
|
|
float summ = retArray[1] * length; |
|
186 |
float percent = biggest_percent; |
float percent = biggest_percent; |
187 |
int i= 2; |
if (noFocus) { |
188 |
|
retArray[0] = noFocus_biggest_percent; |
189 |
|
} else retArray[0] = biggest_percent; |
190 |
|
|
191 |
|
float summ = retArray[0]; |
192 |
|
int i= 1; |
193 |
while (summ < length && i < retArray.length) { |
while (summ < length && i < retArray.length) { |
194 |
retArray[i] = percent * percent_of_predecessor; |
retArray[i] = percent * percent_of_predecessor; |
195 |
if (retArray[i] < smallest_percent) |
if (retArray[i] < smallest_percent) |
196 |
retArray[i] = smallest_percent; |
retArray[i] = smallest_percent; |
197 |
|
|
198 |
summ += retArray[i] * length; |
summ += retArray[i]; |
199 |
percent = retArray[i]; |
percent = retArray[i]; |
200 |
i++; |
i++; |
201 |
} |
} |
203 |
for (int j=i; j<retArray.length; j++) { |
for (int j=i; j<retArray.length; j++) { |
204 |
retArray[j] = 0; |
retArray[j] = 0; |
205 |
} |
} |
|
|
|
|
return retArray; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** Check out the sigmund function." y0 = tanh(y1)" if you like to understand ;) |
|
|
*/ |
|
|
private float[] countSigmund(int ratio) { |
|
|
float [] retArray = new float[ratio]; |
|
|
|
|
|
float I = 10.0f; |
|
|
float sigm = I*(float)Math.PI; |
|
|
float start = 3.0f*(float)Math.PI; |
|
|
|
|
|
if (ratio < 5) start = 6.5f*(float)Math.PI; |
|
|
else if (ratio < 10) start = 5.0f*(float) Math.PI; |
|
|
if (ratio > 50) start = 1.2f*(float)Math.PI; |
|
|
|
|
|
float dx = sigm/ratio; |
|
|
|
|
|
for (int i=0; i<ratio; i++) { |
|
|
retArray[i] = (float) (1/(1+Math.exp(-(start - i*dx)))); |
|
|
|
|
|
if (dbg) pa(i+"Sigm:" +retArray[i]); |
|
|
} |
|
206 |
return retArray; |
return retArray; |
207 |
} |
} |
|
|
|
|
|
|
|
/* Recursive */ |
|
|
private void proportion(float[] arr, int focus, float ideal_ratio) { |
|
|
if ( arr.length == 1) return; |
|
|
|
|
|
float sum = 0; |
|
|
for (int i=0; i<arr.length; i++) { |
|
|
sum += arr[i]; |
|
|
} |
|
|
|
|
|
if (dbg) pa("ideal: "+ ideal_ratio + " this ratio: "+ (sum/arr[focus]) ); |
|
|
|
|
|
// normally just make things smaller |
|
|
if (ideal_ratio < (sum/arr[focus]) ) { |
|
|
for (int i=0; i<arr.length; i++) { |
|
|
if (arr[i] == 1.0f) continue; |
|
|
arr[i] *= 0.9f; |
|
|
} |
|
|
if (dbg) pa("smaller recursive"); |
|
|
proportion(arr, focus, ideal_ratio); |
|
|
return; |
|
|
} |
|
|
} |
|
208 |
} |
} |