Outerra forum
Outerra Engine => Ideas & Suggestions & Questions => Topic started by: dac on August 22, 2014, 09:22:35 am
-
Hello,
I was wondering, how well is suited Outerra for visualizing GIS type information? If I have a list of real life objects with a lat,lon position - is it possible to dynamically add and modify their position in the engine? Imagine having a GPS on a car and visualizing the car move inside the engine based on the real coordinates.
From what i've been able to tell you're currently only able to add static objects via the editor but I could be mistaken.
Is this something that will be possible down the road?
-
You can modify positions and orientations of dynamic objects (like vehicles or aircraft) via script, but you can't easily access external data from the script. This will need an API able to sync positions of objects from outside, with an option to clip the position to terrain height.
-
How much of this is possible in the current alpha version?
The main problem would be to retrieve external data (coming through a web interface, stream or a REST like thing)?
Thanks for the info.
-
There's an IGC interface that allows controlling the camera, maybe it could be extended to allow also spawning vehicles and controlling them, in a limited way. With IGC you can currently write a C++ addon that gets invoked each frame to handle the camera.
-
Thank you for your answers. Is there any material available regarding the API or examples of how to get started?
-
And as a follow up, been looking around the game files. Would my idea be accomplisable if I scripted it via the jquery stuff in \www\.
For instance in your vehicle spawning
$app.spawn_vehicle(selected.attr("id")); is used.
Is it possible to call a spawn script with a specific unique id, a latlon position and model? And then dynamically from within the script (objects stored in a hashmap or similar) update each objects position from an outside source?
Could simply trigger the script when opening one of the maps.
-
Here's some info on IGC & examples: http://forum.outerra.com/index.php?topic=2705.msg28404#msg28404 (http://forum.outerra.com/index.php?topic=2705.msg28404#msg28404)
Also this http://forum.outerra.com/index.php?topic=2210.0 (http://forum.outerra.com/index.php?topic=2210.0)
$app.spawn_vehicle(selected.attr("id")); is used.
Is it possible to call a spawn script with a specific unique id, a latlon position and model? And then dynamically from within the script (objects stored in a hashmap or similar) update each objects position from an outside source?
That id is only valid in that dialog, and it's an id of type, not of instance.
There's a (preliminary) way to create instances through script from ui windows:
var world = $eview.$query_interface("ot::js::world.get");
var v = world.create_instance("outerra/mig29/mig29", pos, rot, false);
...
v.set_pos(p)
v.set_rot(r)
-
Yes I figured the ID was a reference to the selected vehicle in the dialog (ie. which car or truck). But if I have multiple objects spawned in, I would want a way to keep a track of them by using some sort of unique ID.
Is it possible to attach such an ID to an ingame object and then later retrieve them & modify their properties such as location?
Thanks for the help.
-
I've tried to use your example given but it is not working.
Right now i'm trying to spawn a basic object at the latlon 0,0, with 1km height which in the ECEF should be
x = 6370
y = 0
z = 0
http://www.oc.nps.edu/oc2902w/coord/llhxyz.htm (http://www.oc.nps.edu/oc2902w/coord/llhxyz.htm)
The pos looks to be a double3 which isn't a native javascript object as far as I know but i've tried both as
var pos = {
x:6379,
y:0,
z:0
};
Which gives me a Error reading struct opening token fatal error
or simply as
var pos;
pos.x = 6379;
pos.y = 0;
pos.z = 0;
The rest of the code is as you provided
var world = $eview.$query_interface("ot::js::world.get");
var rot = 90;
var v = world.create_instance("outerra/ddg/ddg", pos, rot, false);
//Dynamic update? resetting val
v.set_pos(pos);
v.set_rot(rot);
Either it crashes or nothing happens. I've chosen the large ship, which in position 0.0 should be fairly easy to spot if something was being spawned in.
What am I doing wrong?
Any tips for selecting height to be waveheight in a given position?
I also tried taking the position from the IGC using
var igc = $eview.$query_interface("ot::js::igc.get");
var pos = igc.pos();
Which immediately crashes the software.
Thanks
-
Where are you running the scripts?
A couple of obvious issues - ECEF coordinates should be in meters, and rotation is a quaternion (rotation from ECEF frame). It's rather clumsy to work with these in JS, we will need a vector math library there.
-
I'm attaching a JS file to the mapnav.html OSM
Would it be possible to get a working example which I could modify/learn from?
Thanks for your help
-
I'll try to make some, but only after the next release. Ping me if I forget.
-
Great thanks!
-
Did you get a chance to look at it/address it in the new update?
Thanks
David
-
Not yet, but I'll make an example. Probably including the lat/lon conversion to ECEF - I guess your inputs will be in lat/lon+alt.
-
Great thank you, input would be on lat/lon and possibly alt, using the highest level of either ground or sea-level would also be good.
-
Hey sorry to keep bugging about this, has there been any update?
Thanks
-
Sorry I didn't have time to check it yet. I did a quick test, but encountered some issues. Some quick code to look at (sea level placement):
var world,igc,vehicle;
function ll2xyz(lon,lat) {
const R = 6378135;
const rad = Math.PI/180.0;
var fc = Math.cos(lon*rad);
var fs = Math.sin(lon*rad);
var ac = Math.cos(lat*rad);
return [R*fc*ac, R*fs*ac, R*Math.sin(lat*rad)];
}
if(!world) world = $eview.$query_interface("ot::js::world.get");
if(!igc) igc = $eview.$query_interface("ot::js::igc.get");
if(world && !vehicle) {
var c = map.getBounds().getCenter(); //this is from google maps object
var pos = ll2xyz(c.lng(), c.lat());
vehicle = world.create_instance("outerra/ddg/ddg", pos, {x:0, y:0, z:0, w:1}, false);
}
-
Thanks for your work, i've yet to get anything to function though.
I'm invoking your example code from the Google map load() code, the map loads fine (and I assume the code?) but no vehicles are being created.
It seems to evaluate correctly and execute the create commands but as I mentioned, nothing is being created at the map center.
Do you have it working on your end? Any suggestions?
As always, thanks,
DaC
-
Sorry, there was a bug in that code (erroneously pasted an older one). The ll2xyz function should return {x:R*fc*ac, y:R*fs*ac, z:R*Math.sin(lat*rad)};
Note that this places objects on the sea level, so they will be under the terrain elsewhere. To correct that, add the result of world.elevation(pos) to R.
-
Thank you however there's still some issues. Here's the code I got working if others are interested. There seems to be some issues with getting the map.getBounds().getCenter() however you can also just hardcode a value in for testing. There were also a missing w variable in the pos returned.
function spawnVehicle(){
if(!world) {
world = $eview.$query_interface("ot::js::world.get");
}
if(!igc) {
igc = $eview.$query_interface("ot::js::igc.get");
}
if(world && !vehicle) {
//Hardcoded values, lat lon in decimal
lat = 55.66393055555555;
lon = 12.640802777777777;
var pos = ll2xyz(lon, lat);
vehicle = world.create_instance("outerra/ddg/ddg", pos, {x:0, y:0, z:0, w:0}, false);
}
}
function ll2xyz(lon,lat) {
const R = 6378135;
const rad = Math.PI/180.0;
var fc = Math.cos(lon*rad);
var fs = Math.sin(lon*rad);
var ac = Math.cos(lat*rad);
return {x:R*fc*ac, y:R*fs*ac, z:R*Math.sin(lat*rad), w:1};
}
This will create a ship somewhere near the coast of Denmark.
Any way to rotate the vehicle in creation or after it's been created? Or setting speed, modifying position of an already created vehicle etc?
-
There's no w in position, because it's just a 3D world position. Also, the rotation quaternion should not be all zeros, the last w should be 1 for no rotation from default ECEF frame.
I tested it with map.getBounds().getCenter(), what problems did you have?
Once you get reference to the vehicle, you can use set_pos and set_rot methods to adjust its position and rotation. You can't set the speed directly, because that's a function of vehicle script, of its reaction to throttle and other inputs.
-
You are correct about w, I got it mixed up with the w in the create_instance where it will crash if there's no w :)
If I use the map.getBounds().getCenter() it doesn't seem to execute anything (I'm guessing a Javascript error that I'm unable to see). Using a hard-coded values fixes that.
Using vehicle.set_rot(x); crashes the program with an Fatal error exception - error reading struct opening token
but maybe the create_instance doesn't return the vehicle object?
As always,
Thank you
-
set_rot expects a quaternion (http://en.wikipedia.org/wiki/Quaternion), as an object with x y z w members. With quaternions you actually need to provide all of them, unlike with vectors where the missing elements are set to 0. That's what you probably meant by crashing with no w.