Sie sind nicht angemeldet.

1

Sonntag, 13. Juni 2010, 13:15

Object VR with left/right AND up/down rotation

There have been a couple of requests for multi-row object movies, so I've taken the liberty of modifying Klaus' objectskin.xml code to support rotations about both the Y and X axes. Klaus' original file can be found in the templates/xml/skin directory of the krpanotools 1.0.8.11 release. The new code allows one to turn the object not only left and right, but also up and down. It also supports user controllable autorotation (the autorotate.enabled, autorotate.waittime and autorotate.speed attributes are supported ). I've changed the code so that the user is not forced into panning mode when zoomed in, instead one can pan by pressing the space bar while moving the cursor. Please note that version 1.0.8.11 of the viewer is required as I make one use of the new square root function.

Note: This file is split across two posts due to the character length limitation of the forum. This is part 1 of 2 :

Quellcode

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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
<!--
	krpano 1.0.8.11
	object movie rotate/zoom/move example skin 
-->

<krpano version="1.0.8" onstart="objectvr_init()" >
	<!-- objectvr options
		xframes	[natural integer] the number of frames in each row (number of frames for a complete ath excursion)
		yframes	[natural integer] the number of frames in each column (number of frames for a complete atv excursion)
		startframe	[natural integer] the frame number for the initial view of the object
		hlimit	[boolean] limit the horizontal rotation (set to true for partial object vr's with limited atv rotation)
		autorotate	[boolean] enable autorotation, action objectvr_autorotate(); must be run after enabling
		autorotatedelay [float] time between frame updates for autorotation
	-->
	<objectvr />

	<autorotate speed="200.0" waittime="2" />

	<view fovtype="DFOV"
		limitview="fullrange"
		maxpixelzoom="1.0"
	/>

	<control zoomtocursor="true"
		zoomoutcursor="true"
		mousetype="moveto"
		mousespeed="0"
	/>

	<display flash10="on"
		movequality="HIGH" stillquality="HIGHSHARP"
		movequality10="HIGH" stillquality10="HIGH"
	/>

	<events onenterfullscreen="set(plugin[openfs].visible,false); set(plugin[closefs].visible,true);"
		onexitfullscreen ="set(plugin[openfs].visible,true);  set(plugin[closefs].visible,false);"
		onmousedown="objectvr_halt_autorotate();mdown();"
		onmouseup="mup();"
		onidle="objectvr_autorotate();"
		onkeydown="onkeydown();"
		onkeyup="onkeyup();"
		onresize="objectvr_update_panning();"
		onviewchange="if (objectvr.fullviewfov === null,
					if (view.fov != 90,
						copy(objectvr.fullviewfov,view.fov);
						roundval(objectvr.fullviewfov,1);
						set(events.onviewchange,null);
					);
				);"
	/>
	<action name="objectvr_init">
		if (objectvr.startframe !== null,
			copy(image.frame,objectvr.startframe);
		<!--else-->,
			div(image.frame,image.frames,2);
		);
		if (objectvr.yframes === null,
			if (objectvr.xframes === null,
				objectvr_guess_aspect_ratio();
				if (objectvr.xframes GT 72,
					if (objectvr.yframes == 1,
						error("pow function not available in this version of krpano, use 1.0.8.11 or newer OR set object.xframes");
					);
				);
			<!--else-->,
				div(objectvr.yframes,image.frames,objectvr.xframes);
				roundval(objectvr.yframes);
			);
		<!--else-->,
			if (objectvr.xframes === null,
				div(objectvr.xframes,image.frames,objectvr.yframes);
				roundval(objectvr.xframes);
			);
		);
		if (objectvr.xframes === null,
			div(objectvr.xframes,image.frames,objectvr.yframes);
			roundval(objectvr.xframes);
		);
		if (objectvr.yframes == 1,
			set(plugin[rotateupbg].visible,false);
			set(plugin[rotatedownbg].visible,false);
		);
		if (objectvr.xframes == 1,
			set(plugin[rotateleftbg].visible,false);
			set(plugin[rotaterightbg].visible,false);
		);
		if (objectvr.hlimit != true,
			set(objectvr.xframemax,1);
			copy(objectvr.xframemin,objectvr.xframes);
		<!--else-->,
			copy(objectvr.xframemax,objectvr.xframes);
			set(objectvr.xframemin,1);
		);
		sub(objectvr.yframemax,objectvr.yframes,1);
		sub(objectvr.xframe,image.frame,1);
		mod(objectvr.xframe,objectvr.xframes);
		inc(objectvr.xframe);
		div(objectvr.yframe,image.frame,objectvr.xframes);
		sub(objectvr.yframe,0.5);
		roundval(objectvr.yframe);
		div(objectvr.deltah,360,objectvr.xframes);
		copy(idletime,autorotate.waittime);
		copy(objectvr.autorotate,autorotate.enabled);
		set(autorotate.enabled,false);
		mul(objectvr.xmin,objectvr.yframe,objectvr.xframes);
		inc(objectvr.xmin);
		add(objectvr.xmax,objectvr.xmin,objectvr.xframes);
		dec(objectvr.xmax);
		objectvr_update_panning();
	</action>

	<action name="objectvr_guess_aspect_ratio">
		mul(objectvr.xframes,image.frames,2);
		inc(objectvr.xframes);
		pow(objectvr.xframes,0.5);
		dec(objectvr.xframes);
		roundval(objectvr.xframes);
		div(objectvr.yframes,image.frames,objectvr.xframes);
		roundval(objectvr.yframes);
		mul(action[%0].tmp,objectvr.xframes,objectvr.yframes);
		if (action[%0].tmp != image.frames,
			set(objectvr.xframes,36);
			div(objectvr.yframes,image.frames,objectvr.xframes);
			roundval(objectvr.yframes);
			set(action[%0].tryagain,false);
			if (objectvr.yframes GT 18,
				set(action[%0].tryagain,true);
			);
			mul(action[%0].tmp,objectvr.xframes,objectvr.yframes);
			if (action[%0].tmp != image.frames,
				set(action[%0].tryagain,true);
			);
			if (action[%0].tryagain,
				set(objectvr.xframes,48);
				div(objectvr.yframes,image.frames,objectvr.xframes);
				roundval(objectvr.yframes);
				set(action[%0].tryagain,false);
				if (objectvr.yframes GT 24,
					set(action[%0].tryagain,true);
				);
				mul(action[%0].tmp,objectvr.xframes,objectvr.yframes);
				if (action[%0].tmp != image.frames,
					set(action[%0].tryagain,true);
				);
				if (action[%0].tryagain,
					set(objectvr.yframes,1);
					copy(objectvr.xframes,image.frames);
				);
			);
		);
	</action>

	<!-- objectvr mouse rotate action -->
	<action name="mdown">
		if(control.mousespeed == 0,
			set(mbdown, true);
			set(xlastframepos,null);
			set(ylastframepos,null);
			objectrotate();
		);
	</action>

	<action name="mup">
		set(mbdown, false);
	</action>

	<action name="objectrotate">
		div(mxpos, mouse.x, stagewidth);
		mul(xframepos, mxpos, objectvr.xframes);
		roundval(xframepos);
		div(mypos, mouse.y, stageheight);
		mul(yframepos, mypos, objectvr.yframes);
		roundval(yframepos);

		if(xlastframepos == null, copy(xlastframepos,xframepos));
		if(ylastframepos == null, copy(ylastframepos,yframepos));

		sub(xframemove, xlastframepos, xframepos);
		copy(xlastframepos,xframepos);
		sub(yframemove, ylastframepos, yframepos);
		copy(ylastframepos,yframepos);

		set(xrotatedirection, right);
		if(xframemove LT 0, mul(xframemove,xframemove,-1); set(xrotatedirection, left); );
		set(yrotatedirection, up);
		if(yframemove LT 0, mul(yframemove,yframemove,-1); set(yrotatedirection, down); );
		if(mbdown,
			if(yframemove != 0,
				if(yrotatedirection == down,
					dec(objectvr.yframe,get(yframemove),0,0);
				,
					inc(objectvr.yframe,get(yframemove),get(objectvr.yframemax),get(objectvr.yframemax));
				);
				mul(objectvr.xmin,objectvr.yframe,objectvr.xframes);
				inc(objectvr.xmin);
				add(objectvr.xmax,objectvr.xmin,objectvr.xframes);
				dec(objectvr.xmax);
			);
			sub(objectvr.xframe,image.frame,1);
			mod(objectvr.xframe,objectvr.xframes);
			inc(objectvr.xframe);
			if(xframemove != 0,
				if(xrotatedirection == left,
					dec(objectvr.xframe,get(xframemove),1,get(objectvr.xframemin));
				,
					inc(objectvr.xframe,get(xframemove),get(objectvr.xframes),get(objectvr.xframemax));
				);
			);
			mul(action[%0].tmp,objectvr.yframe,objectvr.xframes);
			add(image.frame,action[%0].tmp,objectvr.xframe);

			delayedcall(0.01,objectrotate());
		);
	</action>

	<action name="startrotateleft">
		set(rotating,true);
		rotateleft();
	</action>

	<action name="startrotateright">
		set(rotating,true);
		rotateright();
	</action>

	<action name="startrotateup">
		set(rotating,true);
		rotateup();
	</action>

	<action name="startrotatedown">
		set(rotating,true);
		rotatedown();
	</action>

	<action name="rotateleft">
		if (objectvr.hlimit != true,
			dec(image.frame,1,get(objectvr.xmin),get(objectvr.xmax));
		<!--else-->,
			dec(image.frame,1,get(objectvr.xmin),get(objectvr.xmin));
		);
		delayedcall(0.02, if(rotating,rotateleft()) );
	</action>

	<action name="rotateright">
		if (objectvr.hlimit != true,
			inc(image.frame,1,get(objectvr.xmax),get(objectvr.xmin));
		<!--else-->,
			inc(image.frame,1,get(objectvr.xmax),get(objectvr.xmax));
		);
		delayedcall(0.02,  if(rotating,rotateright()) );
	</action>

	<action name="rotatedown">
		if (objectvr.yframe LT objectvr.yframemax,
			inc(objectvr.yframe,1,get(objectvr.yframes));
			inc(objectvr.xmin,get(objectvr.xframes));
			inc(objectvr.xmax,get(objectvr.xframes));
			inc(image.frame,get(objectvr.xframes));
		);
		delayedcall(0.02, if(rotating,rotatedown()) );
	</action>

	<action name="rotateup">
		if (objectvr.yframe GT 0,
			dec(objectvr.yframe,1,0);
			dec(objectvr.xmin,get(objectvr.xframes));
			dec(objectvr.xmax,get(objectvr.xframes));
			dec(image.frame,get(objectvr.xframes));
		);
		delayedcall(0.02,  if(rotating,rotateup()) );
	</action>

	<action name="stoprotate">
		set(rotating,false);
	</action>
Note: This file is split across two posts due to the character length limitation of the forum. This was part 1 of 2, see here for part 2
edit 6/19/10--various autorotate bug fixes and improvements per feedback from massimo and bags. Thanks guys!

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »pinsane« (19. Juni 2010, 11:40)


2

Sonntag, 13. Juni 2010, 13:24

Note: This file is split across two posts due to the character length limitation of the forum. This is part 2 of 2, see here for part 1

Quellcode

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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<action name="objectvr_autorotate">
		if (objectvr.autorotate == true,
			if (progress.isloading == true,
				delayedcall(1,objectvr_autorotate());
			<!--else-->,
				set(action[_objectvr_autorotate].halt,false);
				_objectvr_autorotate();
			);
		);
	</action>
	<action name="_objectvr_autorotate">
		if (objectvr.autorotate == true,
			oninterrupt(objectvr_halt_autorotate());
			if (action[%0].halt == true,
				set(action[%0].halt,false);
			<!--else-->,
				if (objectvr.hlimit != true,
					inc(image.frame,1,get(objectvr.xmax),get(objectvr.xmin));
				<!--else-->,
					if (action[%0].dir === null,
						set(action[%0].dir,right);
					);
					if (action[%0].dir == right,
						inc(image.frame,1,get(objectvr.xmax),get(objectvr.xmax));
						if (image.frame GE objectvr.xmax,
							set(action[%0].dir,left);
						);
					<!--else-->,
						dec(image.frame,1,get(objectvr.xmin),get(objectvr.xmin));
						if (image.frame LE objectvr.xmin,
							set(action[%0].dir,right);
						);
					);
				);
				div(objectvr.autorotatedelay,objectvr.deltah,autorotate.speed);
				if (objectvr.autorotatedelay LT 0, <!--BUGFIX strange, somtimes autorotate.speed is negative-->
					mul(objectvr.autorotatedelay,-1);
				);
				delayedcall(get(objectvr.autorotatedelay),_objectvr_autorotate());
			);
		);
	</action>

	<action name="onkeydown">
		if (keycode == 32,
			set(control.mousespeed,10);
			set(control.mousetype,drag2d);
			copy(action[%0].fov,view.fov);
			roundval(action[%0].fov,1);
			if (action[%0].fov GE objectvr.fullviewfov,
				showtext("you must first zoom in order to pan");
			);
<!--uncomment these lines to use hand cursor for dragging (see also onkeyup)
			set(cursors.url, skin/drag-cursors.png);
			set(cursors.type, drag);
			set(cursors.move,  2|0|30|32);
			set(cursors.drag, 37|0|30|32);
-->
		<!--else-->,
			if (keycode == 16,
				objectvr_halt_autorotate();
			<!--else-->,
				if (keycode == 17,
					objectvr_halt_autorotate();
				<!--else-->,
					if (keycode == 37,
						objectvr_halt_autorotate();
					<!--else-->,
						if (keycode == 38,
							objectvr_halt_autorotate();
						<!--else-->,
							if (keycode == 39,
								objectvr_halt_autorotate();
							<!--else-->,
								if (keycode == 40,
									objectvr_halt_autorotate();
								);
							);
						);
					);
				);
			);
		);
	</action>

	<action name="onkeyup">
		if (keycode == 32,
			set(control.mousespeed,0);
			set(control.mousetype,moveto);
<!--uncomment these lines to use hand cursor for dragging (see also onkeydown)
			set(cursors.url,null);
-->
		<!--else-->,
			if (keycode == 16,
				objectvr_update_panning();
			<!--else-->,
				if (keycode == 17,
					objectvr_update_panning();
				);
			);
		);
	</action>

	<action name="showup_rotate_buttons">
		tween(plugin[rotaterightbg].alpha, 0.7, 1.5, easeOutQuad, tween(plugin[rotaterightbg].alpha, 0.0, 2.5, easeInExpo));
		tween(plugin[rotateleftbg].alpha,  0.7, 1.5, easeOutQuad, tween(plugin[rotateleftbg].alpha,  0.0, 2.5, easeInExpo));
		tween(plugin[rotateupbg].alpha, 0.7, 1.5, easeOutQuad, tween(plugin[rotateupbg].alpha, 0.0, 2.5, easeInExpo));
		tween(plugin[rotatedownbg].alpha,  0.7, 1.5, easeOutQuad, tween(plugin[rotatedownbg].alpha,  0.0, 2.5, easeInExpo));
	</action>

	<action name="objectvr_halt_autorotate">
		set(action[_objectvr_autorotate].halt,true);
		invalidatescreen();
	</action>

	<action name="objectvr_update_panning">
		copy(action[%0].tmp,view.hfov);
		roundval(action[%0].tmp,2);
		if (action[%0].tmp LT 1,
			set(plugin[left].alpha,1);
			set(plugin[right].alpha,1);
		<!--else-->,
			set(plugin[left].alpha,0.3);
			set(plugin[right].alpha,0.3);
		);
		copy(action[%0].tmp,view.vfov);
		roundval(action[%0].tmp,2);
		if (action[%0].tmp LT 1,
			set(plugin[up].alpha,1);
			set(plugin[down].alpha,1);
		<!--else-->,
			set(plugin[up].alpha,0.3);
			set(plugin[down].alpha,0.3);
		);
	</action>
	<textstyle name="buttonstyle" font="Arial" fontsize="12" bold="true" italic="true"
		textcolor="0x000000" background="false" border="false"
		blendmode="layer" effect="glow(0xFFFFFF,0.85,4,4);dropshadow(2,45,0x000000,4,1);"
		origin="cursor" edge="bottom" xoffset="15" yoffset="-5" showtime="0.1" fadeintime="0.1" fadetime="0.1"
	/>

	<style name="button" url="%SWFPATH%/skin/buttons.png" zorder="3" keep="true" />

	<plugin name="in"       align="bottom" x="-140" y="10" style="button" crop="160|0|40|40" onovercrop="160|40|40|40" ondowncrop="160|80|40|40" onhover="showtext('Zoom IN ', buttonstyle);"   ondown="objectvr_halt_autorotate();set(movevectorz,-1);"  onup="set(movevectorz,0);objectvr_update_panning();" />
	<plugin name="out"      align="bottom" x="-100"  y="10" style="button" crop="200|0|40|40" onovercrop="200|40|40|40" ondowncrop="200|80|40|40" onhover="showtext('Zoom OUT ', buttonstyle);"  ondown="objectvr_halt_autorotate();set(movevectorz,+1);"  onup="set(movevectorz,0);objectvr_update_panning();" />
	<plugin name="left"     align="bottom" x="-60"  y="10" style="button" crop=  "0|0|40|40" onovercrop=  "0|40|40|40" ondowncrop=  "0|80|40|40" onhover="showtext('Pan Left ', buttonstyle);"  ondown="objectvr_halt_autorotate();set(movevectorx,-1);"  onup="set(movevectorx,0);" />
	<plugin name="right"    align="bottom" x="-20"    y="10" style="button" crop= "40|0|40|40" onovercrop= "40|40|40|40" ondowncrop= "40|80|40|40" onhover="showtext('Pan Right ', buttonstyle);" ondown="objectvr_halt_autorotate();set(movevectorx,+1);"  onup="set(movevectorx,0);" />
	<plugin name="up"       align="bottom" x="+20"  y="10" style="button" crop= "80|0|40|40" onovercrop= "80|40|40|40" ondowncrop= "80|80|40|40" onhover="showtext('Pan Up ', buttonstyle);"    ondown="objectvr_halt_autorotate();set(movevectory,-1);"  onup="set(movevectory,0);" />
	<plugin name="down"     align="bottom" x="+60"  y="10" style="button" crop="120|0|40|40" onovercrop="120|40|40|40" ondowncrop="120|80|40|40" onhover="showtext('Pan Down ', buttonstyle);"  ondown="objectvr_halt_autorotate();set(movevectory,+1);"  onup="set(movevectory,0);" />
	<plugin name="autorotate"     align="bottom" x="+100"  y="10" style="button" crop="240|0|40|40" onovercrop="240|40|40|40" ondowncrop="240|80|40|40" onhover="showtext('Toggle Autorotate ', buttonstyle);"  onclick="switch(objectvr.autorotate);objectvr_autorotate();" />
	<plugin name="openfs"   align="bottom" x="+140" y="10" style="button" crop="280|0|40|40" onovercrop="280|40|40|40" ondowncrop="280|80|40|40" onhover="showtext('Fullscreen ', buttonstyle);"      onclick="set(fullscreen,true);"  visible="true"  />
	<plugin name="closefs"  align="bottom" x="+140" y="10" style="button" crop="320|0|40|40" onovercrop="320|40|40|40" ondowncrop="320|80|40|40" onhover="showtext('Exit Fullscreen ',buttonstyle);"  onclick="set(fullscreen,false);" visible="false" />


	<plugin name="rotaterightbg" url="%SWFPATH%/skin/black.png" align="right" width="125" height="100%" alpha="0.0" zorder="1" onover="tween(plugin[rotaterightbg].alpha,0.7);" onout="tween(plugin[rotaterightbg].alpha,0);" ondown="objectvr_halt_autorotate();startrotateleft();"  onup="stoprotate();" />
	<plugin name="rotateleftbg"  url="%SWFPATH%/skin/black.png" align="left"  width="125" height="100%" alpha="0.0" zorder="1" onover="tween(plugin[rotateleftbg].alpha,0.7);"  onout="tween(plugin[rotateleftbg].alpha,0);"  ondown="objectvr_halt_autorotate();startrotateright();" onup="stoprotate();" />
	<plugin name="rotateupbg" url="%SWFPATH%/skin/black.png" align="top" width="100%" height="125" alpha="0.0" zorder="1" onover="tween(plugin[rotateupbg].alpha,0.7);" onout="tween(plugin[rotateupbg].alpha,0);" ondown="objectvr_halt_autorotate();startrotatedown();"  onup="stoprotate();" />
	<plugin name="rotatedownbg"  url="%SWFPATH%/skin/black.png" align="bottom" width="100%" height="125" alpha="0.0" zorder="1" onover="tween(plugin[rotatedownbg].alpha,0.7);"  onout="tween(plugin[rotatedownbg].alpha,0);"  ondown="objectvr_halt_autorotate();startrotateup();" onup="stoprotate();" />

	<plugin name="rotaterighticon" url="%SWFPATH%/skin/arrow.png" align="right" x="10" scale="0.5" zorder="2" enabled="false" parent="rotaterightbg" />
	<plugin name="rotatelefticon"  url="%SWFPATH%/skin/arrow.png" align="left" edge="right" rotate="180" x="10" scale="0.5" zorder="2" enabled="false"  parent="rotateleftbg" />
	<plugin name="rotateupicon" url="%SWFPATH%/skin/arrow.png" align="top" edge="right" y="10" scale="0.5" rotate="-90" zorder="2" enabled="false" parent="rotateupbg" />
	<plugin name="rotatedownicon"  url="%SWFPATH%/skin/arrow.png" align="bottom" edge="right" rotate="90" y="60" scale="0.5" zorder="2" enabled="false"  parent="rotatedownbg" />

</krpano>
Note: This file is split across two posts due to the character length limitation of the forum. This was part 2 of 2, see here for part 1
edit 6/19/10--various autorotate bug fixes and improvements per feedback from massimo and bags. Thanks guys!

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »pinsane« (19. Juni 2010, 11:44)


3

Sonntag, 13. Juni 2010, 14:07

The object VR is composed of a series of photographs that are ordered in a specific manner that allows the action to properly access a specific picture. These photos are ordered by name, a simple way to do this is to name them pic0001.tif, pic0002.tif, pic0003.tif, etc. The kmakemultires program uses the names of the file supplied to put the frames in order.

When naming your files, you should use leading zero padding in your name, that is, all numbers should be represented by the same number of digits, using leading zeros to fill out the number. For example, if you have 196 pictures, your numbers should always be represented with 3 digits (because 196 uses three digits). Thus name your files image001.tif, image002.tif, ... ,image009.tif,image010.tif,image011.tif, ... ,image099.tif,image100.tif,image101.tif, ... ,image191.tif,image192.tif. Because kmakemultires sorts the file names using alphabetic sorting, files named using leading zeros will be sorted correctly and produce the proper ordering for your frames. If you instead choose to name things image1.tif, image2.tif, ... ,image191.tif,image192.tif, the current versions of kmakemultires (1.0.8.10 or 1.0.8.11) will incorrectly sort your frames image1.tif,image10.tif,image11.tif,image12.tif, etc.

For a 2 axes object vr, we can consider the pictures to be organized in a grid. Each row of the grid contains a complete counterclockwise revolution around the object at a given altitude. Each column of the grid contains a vertical transition from a high altitude (limited by -90 degrees--the top of the object) to a low altitude (limited by 90 degrees--the bottom of the object). To use an analogy with a standard panorama each row contains all pictures with a given ath while each column contains all pictures with a particular atv. Each picture is names starting from the upper left corner, moving across each row and then returning to the leftmost column of the next row when a given row is completed.

Let's call the angle change between each picture in a row deltah; this is the incremental angle change about the y axis. We'll refer to the angle changes in each column as deltav; this is the incremental angle change about the x axis. The smaller the angle change between pictures, the smoother the objectvr will turn but the larger the number of pictures that need to be captured. 360 must be evenly divisible by the horizontal angle between pictures (ie. 360/deltah must be an integer) to avoid jerkiness when rotating around the object. Similarly 180 must be evenly divisible by the vertical angle between pictures (ie 180/deltav must be an integer). Many people use 10 degrees as the delta angle, but I prefer the smoother 7.5 degrees.

If you wish to provide full coverage of an object (a view from every perspective), and want the deltav to equal the deltah (which provides uniform rotations in each direction) then the number of photographs required is:
number of pictures per row = 360/deltah
number of pictures per column = 180/deltav+1
The +1 for the column is required because you don't wrap all the way around the sphere, so to get coverage of both the top and bottom of the object, you need to add 1 row.

Here's the layout and numbering of the pictures for a 7.5 degree example:

Quellcode

1
2
3
4
5
6
7
8
9
10
atv\ath    -172.5	   -165.0	  -157.5	...	      0		...	   165.0	   172.6	   180
-90.0	pic0001.tif	pic0002.tif	pic0003.tif	...	pic0024.tif	...	pic0046.tif	pic0047.tif	pic0048.tif
-82.5	pic0049.tif	pic0050.tif	pic0051.tif	...	pic0072.tif	...	pic0094.tif	pic0095.tif	pic0096.tif
-75.0	pic0097.tif	pic0098.tif	pic0099.tif	...	pic0120.tif	...	pic0142.tif	pic0143.tif	pic0144.tif
 ...        ...		     ...	     ...	...	     ...	...	     ...	     ...	     ...
   0	pic0577.tif	pic0578.tif	pic0579.tif		pic0600.tif	...	pic0622.tif	pic0623.tif	pic0624.tif
 ...        ...		     ...	     ...	...	     ...	...	     ...	     ...	     ...
 75.0	pic1057.tif	pic1058.tif	pic1059.tif	...	pic1080tif	...	pic1102.tif	pic1103.tif	pic1104.tif
 82.5	pic1105.tif	pic1106.tif	pic1107.tif	...	pic1128.tif	...	pic1150.tif	pic1151.tif	pic1152.tif
 90.0	pic1153.tif	pic1154.tif	pic1155.tif	...	pic1176.tif	...	pic1998.tif	pic1999.tif	pic1200.tif


Given that each photograph is taken 7.5 degrees apart, the size of the grid is 48 photographs wide (48 * 7.5 = 360 degrees) and 25 photos up and down. 25 photos are needed to cover from zenith to nadir (24 * 7.5 = 180 degrees plus one extra so that both the zenith and nadir are covered).

Each row of photographs starts from behind the object of interest (atv = -172 degrees), travels around the object in a counterclockwise manner and finishes exactly behind the object at (atv = 180 degrees). If you sequence through the photographs in any row it will appear that the object is turning clockwise 360 degrees from a constant altitude.

Each column shows the same atv value for the object, but goes from top (ath=-90) to bottom (ath=90) in 7.5 degree increments.

Once every picture is properly named, you can use kmakemultires with the object.config file found in the templates directory. I've found that in windows, you can't use the droplet with a large number of files, so using the command line version is necessary.

Good luck!

steve

4

Montag, 14. Juni 2010, 00:58

Hi Steve,

That seems to be exciting *smile* , an other great effort of yours *thumbup* ... The only problem is that I have no full 360 object to try the code *rolleyes* ... So, I am waiting to see a resulting example from some one *squint* ...

SAlut.

5

Montag, 14. Juni 2010, 02:06

another great contibution Pinsane, Thank You!

Tuur

Erleuchteter

Beiträge: 2 902

Wohnort: Netherlands

Beruf: Krpano custom coding / Virtual Tours / Photography / Musician / Recording engineer

  • Nachricht senden

6

Montag, 14. Juni 2010, 10:40

...

I think we upgrade Pinsane to professional.. Klaus?

Great!

Thanx Steve for your great TuT again *thumbup*
You get a full weekend free drinks in the 'bar'.

Cheers

Tuur *thumbsup*
http://www.virtualtuur.com
Skype:studiotuur

bulp

Fortgeschrittener

Beiträge: 389

Wohnort: Malaysia

  • Nachricht senden

7

Montag, 14. Juni 2010, 14:19

Thank you very much Pinsane!! *thumbsup*

8

Dienstag, 29. März 2011, 04:24

how to have full 360 in both horiz and vert orientations?

hi there --

awesome (and working) code example... many thanks!

i don't see, easily, how to have a full 360 rotation in vertical orientation. i have an object which will need to rotate fully vertically, and limited horizontally. Ideas? A pointer to what to modify in the code would be fine -- it appears to me to limit the y rotation by default, to the number of rows minus 1. *question*

thanks in advance!

9

Sonntag, 8. Mai 2011, 09:32

Great job!

I tested it and works great for me! thanks so much Pinsane!! you're the best. *thumbsup* *squint*
 

*whistling* mail: Bludream@gmail.com,

bulp

Fortgeschrittener

Beiträge: 389

Wohnort: Malaysia

  • Nachricht senden

10

Sonntag, 5. Juni 2011, 04:47

bludream would u share the sample working demo ?

danimorgo

Anfänger

Beiträge: 42

Wohnort: argentina

Beruf: diseñador

  • Nachricht senden

11

Samstag, 19. Oktober 2013, 03:09

is there any link to view an example

12

Samstag, 16. April 2016, 22:10

VRAP - desktop VR content player based on krpano.
Common tasks in one place in one click! Discussion thread
DOWNLOAD for MAC
DOWNLOAD for WIN

samadi

Anfänger

Beiträge: 23

Wohnort: Iran

Beruf: Tehran,Alborz,nazarabad,

  • Nachricht senden

13

Samstag, 9. September 2017, 15:22

this is an old example of 360 degree rotation object
http://livepano.ir/images/vr/sony360/html5/3600-3600.html
samadi
http://www.livepano.ir

Ähnliche Themen