terrain visualization -凯发k8网页登录
this example illustrates the possibility to convert generally available digital elevation models into x3d format for use in virtual reality scenes.
as a source of terrain data, south san francisco dem model has been used. a simple pre-created boeing® 747® model is included in the scene to show the technique of creating virtual scenes from several sources on-the-fly.
this example requires mapping toolbox.
reading dem data
% gunzip the south san francisco dem file to a temporary directory filenames = gunzip('sl3d_sanfranciscos.dem.gz', tempdir); demfilename = filenames{1}; % read the 1:24,000 dem file % standardize missing values to nan deminfo = georasterinfo(demfilename); z = standardizemissing(readgeoraster(demfilename), deminfo.missingdataindicator); % delete the temporary gunzipped file delete(demfilename);
data preparation
manipulation of the data to prepare it for creating virtual world
demdata=z; [xdim, zdim] = size(demdata); xspace = 30; % scaling in meters for x dimension zspace = 30; % scaling in meters for z dimension % reshape the data into a one-dimensional array demdata = demdata(:);
create a virtual world from the template
% bring up template myworld = vrworld('vr_template_terrain.x3d'); % open the virtual world open(myworld); % create a handle to a node vrterrain, the node that will contain the dem data terrain_node = vrnode(myworld,'vrterrain');
create terrain node fields (shape, appearance, material)
% create a child of vrterrain - shape newshape = vrnode(terrain_node, 'children', 'terrain_shape', 'shape'); % create appearance field for the shape newappear = vrnode(newshape, 'appearance', 'terrain_appearance', 'appearance'); % create material field for the appearance newmat = vrnode(newappear, 'material', 'terrain_material','material'); % assign properties for the material field newmat.ambientintensity = 0.25; newmat.diffusecolor = [0.9 0.6 0.6]; newmat.shininess = 0.078125; newmat.specularcolor = [0.0955906 0.0955906 0.0955906]; % create geometry field for the shape newegrid = vrnode(newshape, 'geometry', 'dem_egrid','elevationgrid'); % assign properties for the geometry field - use dem data newegrid.creaseangle = 3.14; newegrid.xdimension = xdim; newegrid.zdimension = zdim; newegrid.xspacing = xspace; newegrid.zspacing = zspace; newegrid.height = demdata; newegrid.ccw = 'true'; % this setting will make the terrain surface visible from both sides newegrid.solid = 'false';
create the terrain texture
for coloring the terrain texture we will use the demcmap function available in mapping toolbox.
% terrain elevation is used to color the image cmap = demcmap(z, 256); % create texture subdirectory of the current directory % output arguments used only to avoid warning message when the directory % already exists [~, ~] = mkdir('texture'); % scale the height values to use the full colormap range % scaling relies on the fact that this terrain begins at zero height zscaled = z .* (size(cmap,1)-1) ./ max(z(:)); % save the texture into png image in the texture subdirectory % rotate the image left to match image orientation needed in x3d model % elements of zscaled represent indices into cmap imwrite(rot90(zscaled), cmap, 'texture/sanfrancisco_elev.png');
assign texture to the vrterrain appearance field
texture image file is created by the code above, here it is included in the x3d scene, as a texture field of the terrain appearance node:
newtexture = vrnode(newappear, 'texture', 'terrain_texture','imagetexture'); newtexture.url = 'texture/sanfrancisco_elev.png';
copy files inlined in the created file to the current directory
inlined models are in the sl3ddemos directory.
because files are inlined using relative path, we must copy them to the same directory where the newly created scene file exists.
if you copy the terrain model to a different location, don't forget to copy also these files, as well as texture file(s) to be found in the texture subdirectory.
% copy b747.x3d from /sl3ddemos to the current directory pt = fileparts(which('vrterrain_simple.m')); copyfile(fullfile(pt, 'b747.x3d'), pwd, 'f');
add the airplane to the virtual scene
% create a new transform node, called "boeing" plane = vrnode(myworld, 'boeing', 'transform'); plane_inline = vrnode(plane, 'children', 'boeing_inline', 'inline'); % a simple model of boeing is prepared in the /sl3ddemos directory plane_inline.url='b747.x3d';
determine the highest peak in the terrain data
ypeak = max(z(:)); [xmax, zmax] = find(z==ypeak); % use the first peak, if more vertices have the same maximum height % convert matrix indices to meters in x and z directions in x3d xpeak=xspace*(xmax(1)-1); zpeak=zspace*(zmax(1)-1);
position the airplane 200 meters above the peak
plane.translation = [xpeak ypeak 200 zpeak]; % scale the size of the airplane by a factor of 20, so that it % is visible in the virtual scene without any extra zooming plane.scale = [20 20 20];
add the coordinate system triad to the virtual scene
it is sometimes useful to temporarily include in the scene a triad that can help with the orientation of objects added to the scene. triad is simply created as an instance of triad externproto which is located in "vrterrain_sanfrancisco.x3d" file.
% % the triad consists of 3 lines (1 meter long) running from one vertex % along the x, y and z directions. the lines are coloured as follows: % x - red % y - green % z - blue % % if the triad is included in the scene at the top level of the scene % hierarchy, it denotes the global scene coordinates. % if it is included as a child of a transform node, it denotes the local % coordinate system (orientation) of that node in the scene. % add the triad to the scene at the top level of the hierarchy triad = vrnode(myworld, 'triad1', 'triad'); % scale the size of the triad so that it is visible % in the virtual scene without any extra zooming triad.scale = [xdim*xspace/8 min(xdim*xspace/8, zdim*zspace/8) zdim*zspace/8]; % position the triad at the center of boeing 747 triad.position=[xpeak ypeak 200 zpeak];
change the template file worldinfo information
change the title of the scene to reflect the changes we made
myworld.world_info.title = 'b747 flying over the san francisco area';
save the created world to a new wrl file
save(myworld, 'vrterrain_sanfrancisco.x3d');
close and delete the virtual world used to create the scene
close(myworld); delete(myworld);
open and view the virtual world file we have just created
there are several alternatives how to open a virtual scene file:
% this is how to open a x3d file in the external viewer: % vrview('terrain.x3d', '-web'); % this is how to open a x3d file in the internal viewer: % vrview('terrain.x3d', '-internal'); % this is how to open the x3d file in the default viewer: createdworld = vrview('vrterrain_sanfrancisco.x3d'); % set antialiasing on to smooth the terrain texture myfig = get(createdworld,'figures'); set(myfig, 'antialiasing', 'on');
cleanup
this example has created a new virtual model in the working directory.
the newly created virtual scene is left open so that you can explore it.
% clear all used variables clear terrain_node z zscaled cmap createdworld demfilename demdata ex filenames ... id lat lon mess myfig myworld newappear newegrid ... newmat newshape newtexture nm ok plane plane_inline pt triad ... ve xdim xmax xpeak xspace ypeak zdim zmax zpeak zspace