Jump to content
Sign in to follow this  
Albert Schweitzer

Camera script required for taking photos of map clusters

Recommended Posts

I want to make a huge, highly detailed and zoomable map of Utes (to start with) and implement it into our TopographicMind Editor, which is like GoogleEarth but in Flash with far more options.

So start of with, I would have to take photos of the map, dividing it into several hundred tiles. In other words I would have to write a cam script in which the camera starts at the top left corner of the map, then waits for 2 seconds giving me time enough to make a screenshot of the area below and then again jumps 100 metres further to the right where I take a photo of the region next to it. After having finished one row I probably end up with 40 images which I could put together in photoshop.

The next step would be to start the same thing once again just with one row lower than the previous, again moving from left to right. So all in all I suppose I would get 40 rows of 40 images each.

But how to? Lets assume this is an ordinary cam script.

~2

ShowCinemaborder false

_camera = "camera" camcreate [0,0,0]

_camera cameraeffect ["internal", "back"]

~2

;=== Starting point! Row 1, moving left to right

_camera camPrepareTarget [1858.15,6280.29,-99714.06]

_camera camPreparePos [1823.79,4726.84,274.28]

_camera camPrepareFOV 0.700

_camera camCommitPrepared 0

@camCommitted _camera

~2

;=== Second photo, moving one step to the right.

_camera camPrepareTarget [1858.15,6280.29,-99714.16]

_camera camPreparePos [2052.01,4738.58,274.22]

_camera camPrepareFOV 0.700

_camera camCommitPrepared 0

@camCommitted _camera

;===x coordinates are West-East.

;===y coordinates are South-North.

;===z coordinate is height above ground.

Of course it would be silly to previously define each and every camera position. I would need an automated formula, that makes the camera automatically move just a 100 metre to the left, then after two seconds again, and again and again.

For the second row I would just copy paste this script and just start with a camera angle a hundred metre below the previous starting point.

Anyone a hint of how to tell the camera that the next position is just +100 metres to the right?

Edited by Albert Schweitzer

Share this post


Link to post
Share on other sites

Hi,

You will treat the camera position and the target position by the variable.

Whenever the loop is repeated, an arbitrary amount changes the value of a variable.

; Initial position
_target_position = [1858.15,6280.29,-99714.06]
_camera_position = [1823.79,4726.84,274.28]

#loop

_target_position = [ (_target_position select 0) + 100, _target_position select 1, _target_position select 2 ]
_target_position = [ (_camera_position select 0) + 100, _camera_position select 1, _camera_position select 2 ]

~2

goto "loop"

Share this post


Link to post
Share on other sites

hmm, the camera is somehow unwilling to move:

~2

ShowCinemaborder false

_camera = "camera" camcreate [0,0,0]

_camera cameraeffect ["internal", "back"]

~2

; Initial position

_target_position = [1858.15,6280.29,-99714.06]

_camera_position = [1823.79,4726.84,274.28]

#loop

_target_position = [ (_target_position select 0) + 100, _target_position select 1, _target_position select 2 ]

_target_position = [ (_camera_position select 0) + 100, _camera_position select 1, _camera_position select 2 ]

~2

goto "loop"

I simply created a solder and entered "this exec "camera1.sqs" into it. That was the way how it worked in ArmA1. Did anything change?

Share this post


Link to post
Share on other sites

It is necessary to update the position and the target of the camera.

~2

ShowCinemaborder false

_camera = "camera" camcreate [0,0,0]

_camera cameraeffect ["internal", "back"]

_camera camSetFov 0.7

; Initial position

_target_position = [1858.15,6280.29,-99714.06]

_camera_position = [1823.79,4726.84,274.28]

#loop

_target_position = [ (_target_position select 0) + 100, _target_position select 1, _target_position select 2 ]

_camera_position = [ (_camera_position select 0) + 100, _camera_position select 1, _camera_position select 2 ]

_camera setPosASL _camera_position

_camera camSetTarget _target_position

_camera camCommit 0

~2

goto "loop"

Share this post


Link to post
Share on other sites

Oh hell, that works smooth as hell! :yay:

I increased the the value from 100 to 400 and nearly get borderless screenshots of clusters which I can put next to each other in Photoshop.

After finishing the first row, would you know a way of how to jump one row down by 400 metres? It doesnt have to work automatically, i could easily go back to the desktop and change it manually in the camera script.

Is that how it works, and then I just always change this value to go one row down?

~2

ShowCinemaborder false

_camera = "camera" camcreate [0,0,0]

_camera cameraeffect ["internal", "back"]

_camera camSetFov 0.7

; Initial position

_target_position = [1858.15,6280.29,-99714.06]

_camera_position = [1823.79,4726.84,274.28]

~1

; for starting to take photos of the second row

_target_position = [ _target_position select 0, (_target_position select 1) - 100, _target_position select 2 ]

_camera_position = [ _camera_position select 0, (_camera_position select 1) - 100, _camera_position select 2 ]

~2

#loop

_target_position = [ (_target_position select 0) + 400, _target_position select 1, _target_position select 2 ]

_camera_position = [ (_camera_position select 0) + 400, _camera_position select 1, _camera_position select 2 ]

_camera setPosASL _camera_position

_camera camSetTarget _target_position

_camera camCommit 0

~2

goto "loop"

Share this post


Link to post
Share on other sites

It is good to use the counter variable specifying the number of capture taken by the row.

_row = 0

_count = 0

~2

ShowCinemaborder false

_camera = "camera" camcreate [0,0,0]

_camera cameraeffect ["internal", "back"]

_camera camSetFov 0.7

; Initial position

_target_position = [1858.15,6280.29,-99714.06]

_camera_position = [1823.79,4726.84,274.28]

#loop

_count = _count + 1

?(_count == 10) : _row = _row + 400; _count = 0

_target_position = [ (_target_position select 0) + 100, (_target_position select 1) + _row, _target_position select 2 ]

_camera_position = [ (_camera_position select 0) + 100, (_camera_position select 1) + _row, _camera_position select 2 ]

_camera setPosASL _camera_position

_camera camSetTarget _target_position

_camera camCommit 0

~2

goto "loop"

Share this post


Link to post
Share on other sites

Thank you Gigan,

I am feeling bad asking you for further advise. But you just play in the scripting advanced league while I am barely a beginner. I tried experimenting blindly with the variables you provided but unfortunately I failed to find out about all of their functions.

So here are precise questions:

rows.jpg

Just by copy pasting your code into the camera script I achieved to do the first horzintal row: jumping 400 metres to the left, waiting 2 secs, then jumping another 400 metres and so on.

1. What variable is responsible to define when to jump to row B?

2. Which value to set to 350 to make the second row to start precisely 350 metres beneath the starting point?

3. From the values provided above I have the impression that the camera moves along row A along a perfect horizontal line. However when attaching the screenshots I took I find that there appears to be a slight difference between them? Something wrong with the focus you thing? Something odd about the starting point of the camera (focus,angle, whatever)?

I am well aware of the effort you put in and I promise to keep working on the map untill it is finished (many hours of input for sure):)

Share this post


Link to post
Share on other sites

Sounds like a very interesting project.

Copy this to your init.sqf file.

In the editor, place a marker called "BottomLeft" at the bottom left corner of the map.

Place a marker called "TopRight" at the top right corner of the map.

You will need to set the altitude you are happy with.

Note this code starts at the _bottom_ row and moves up - I assume that's irrelevant for you but if you really want to start at the top use..

(_startPos select 1) + _height - (_y * _stepy),

as the innermost line.


survey={
_stepX=400 ;
_stepY=350 ;
_startPos = markerpos "BottomLeft";
_endPos=markerpos "TopRight" ;
_altitude=500;
_delay = 2 ;
_width  = (_endPos select 0) - (_startPos select 0);
_height = (_endPos select 1) - (_startPos select 1);


//cam create here

ShowCinemaborder false;
_cam = "camera" camcreate [1,1,1];
_cam cameraeffect ["internal", "back"];
_cam camSetFov 0.7;


for "_y" from 0 to floor (_height/_stepY) do {
    for "_x" from 0 to floor (_width/_stepX) do {
  _pos = [ (_startPos select 0) + (_x * _stepx),
	   (_startPos select 1) + (_y * _stepy),
	   _altitude 
       ] ;
  _cam setPosASL _pos ;
  _pos set[2,0] ;
  _pos set [1,(_pos select 1)+1] ;//avoid gimbal lock
  _cam camsetTarget _pos ;
  _cam camcommit 0;
  sleep _delay ;
    } ;
} ;
};

[] spawn {sleep 1; call survey;} ;

Edited by sbsmac

Share this post


Link to post
Share on other sites

There was a defect in the code which I presented :p

This is the code which operates well.

~2

; Initialization variables.

_row = 0

_count = 0

; Create camera.

ShowCinemaborder false

_camera = "camera" camcreate [0,0,0]

_camera cameraeffect ["internal", "back"]

; If you need the not distorted photograph, make a value small and raise the altitude of a camera.

_camera camSetFov 0.7

; Initial camera position and target position.

_campos = [1823.79,4726.84,274.28]

_tgtpos = [1858.15,6280.29,-99714.06]

; Processing loop.

#loop

; A camera is moved to the appointed place.

_camera setPosASL [ (_campos select 0) + (400 * _count), (_campos select 1) - _row, _campos select 2 ]

_camera camSetTarget [ (_tgtpos select 0) + (400 * _count), (_tgtpos select 1) - _row, _tgtpos select 2 ]

_camera camCommit 0

; If a camera moves horizontally 8 times, a row will be changed 350m.

?(_count == 8) : _row = _row + 350; _count = 0

; The number of times of camera movement is counted.

_count = _count + 1

~2

goto "loop"

Moreover, probably, it will be good for the way of sbsmac code having more flexibility and studying a sqf script.

Share this post


Link to post
Share on other sites

sbsmac, that script realy works like a beauty!!!!:yay:

The only problem I will face will have to do with photoshop and max-image size. But I will report about that later when progressing.

Share this post


Link to post
Share on other sites

Good:-) I'll be really interested to see the end-result - can you update this thread when you have it ?

Share this post


Link to post
Share on other sites
Good:-) I'll be really interested to see the end-result - can you update this thread when you have it ?

Oh, dont worry about that. I used zoomify to show a quick first result as test. The final engine will be a completely different one (our topnotch topographicmind). It seems something is still fishy. Of course the lightning effects will have an impact and make the clusters appear different in color. But nevertheless it appears I have problems attaching them, maybe because they dont have the same fov, foc, whatever. Any guess?

(this is just a quick test, ignore the bad tiles on each ends. But you notice the dimension gaps on the tiles in the middle. There was just no way to make them fit properly one against each other)

http://1aschnitzel.com/zoomify/TemplateWebPage.htm

BTW: dont be mistaken, I am for a much higher detail level, rabbits included.

Share this post


Link to post
Share on other sites

Looks very nice ! The affect you are seeing may be because the angle of the camera is slightly different each time. (The target pos is relative to ground level rather than sea-level). It has to be not-quite-vertical to avoid a gimbal-lock problem. Try replacing the line

_pos set[2,0] ;

with

_pos set[2,-10000] ;

This should make the camera angle variation much less and hopefully you should get better results.

*EDIT* Just a thought but to save you a lot of manual button pressing, you may be able to find a screen-capture utility which will allow you to take a movie at a very slow frame-rate.

For example, http://taksi.sourceforge.net/ seems to allow you to set completely arbitrary frame-rates like 1 frame every 2 seconds.

Of course, you would then need to extract these frames in such a way as your map utility can handle them. You also have the problem of synchronising the capture rate with the arma script rate - over time they will drift apart and you will end up with extra or missing tiles.

Edited by sbsmac

Share this post


Link to post
Share on other sites

Ah, I've just realised what the problem is. The camera frustum wil intersect the land with different areas depending upon the land elevation. This picture gives you and idea of what's going on...

Black triangles represent camera viewing angles, green is a cross-section of the landscape and red horizontal lines represent the tiles you will get.

tiles.jpg

To solve this, try setting a very high camera altitude and a correspondingly small FOV.

Share this post


Link to post
Share on other sites

Understood and Will do! lol, it seems we are getting a little bit scientific here! :D

As far as the image capturing process is concerned, that is actually a pretty simple thing. FRAPS has function that supports taking screenshots in predefined sequences. But I rather do it manually since the ArmA does not realy obey the "~2" second command in the script.

Edited by Albert Schweitzer

Share this post


Link to post
Share on other sites

>But I rather do it manually since the ArmA does not realy obey the "~2" second command in the script.

You can get much better frame timing with this code which may enable you to automate the capture process...

survey={
_stepX=400 ;
_stepY=350 ;
_startPos = markerpos "BottomLeft";
_endPos=markerpos "TopRight" ;
_altitude=500;
_width  = (_endPos select 0) - (_startPos select 0);
_height = (_endPos select 1) - (_startPos select 1);


//cam create here

ShowCinemaborder false;
_cam = "camera" camcreate [1,1,1];
_cam cameraeffect ["internal", "back"];
_cam camSetFov 0.7;


_delay = 2 ;
_startTime=diag_tickTime ;
_frame=1 ;
for "_y" from 0 to floor (_height/_stepY) do {
    for "_x" from 0 to floor (_width/_stepX) do {
  _pos = [ (_startPos select 0) + (_x * _stepx),
	   (_startPos select 1) + (_y * _stepy),
	   _altitude 
       ] ;
  _cam setPosASL _pos ;
  _pos set[2,0] ;
  _pos set [1,(_pos select 1)+1] ;//avoid gimbal lock
  _cam camsetTarget _pos ;
  _cam camcommit 0;
  waituntil{diag_tickTime >=(_starttime + _delay*_frame) } ;
  _frame=_frame+1 ;
    } ;
} ;
};

[] spawn {sleep 1; call survey;} ;


Edited by sbsmac

Share this post


Link to post
Share on other sites

I updated the link in my previous post. But as you can see even with a fov of 0.20 I still fight with tremendous gaps. Of course this just a quick&dirty first try but it showed that I have to experiment a little more.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×