这个示例说明了将一般可用的数字高程模型转换为X3D格式以用于虚拟现实场景的可能性。
作为地形数据的来源,采用了南旧金山DEM模型。一个简单的预先创建的波音®747®模型包括在场景中,以显示创建虚拟场景的技术,从多个来源的飞行。
这个例子需要Mapping Toolbox。
% gunzip南旧金山DEM文件到一个临时目录文件名= gunzip (“sl3d_sanfranciscos.dem.gz”, tempdir);demFilename ={1}文件名;%读取1:24 000 DEM文件将缺失值标准化到NaNdeminfo = georasterinfo (demFilename);Z = standzemissing (readgeoraster(demFilename), deminfo. missingdatindicator);%删除临时gunzip文件删除(demFilename);
操纵数据,为创建虚拟世界做准备
demdata = Z;[xdim, zdim] = size(demdata); / /数据大小xspace = 30;x维度以米为单位缩放百分比zspace = 30;%缩放米为z维%将数据重新格式化为一维数组demdata = demdata (:);
打开模板myworld = vrworld (“vr_template_terrain.x3d”);打开虚拟世界打开(myworld);%创建一个节点VRTerrain的句柄,该节点将包含DEM数据Terrain_node = vrnode (myworld,“VRTerrain”);
创建一个VRTerrain - shape的子对象newShape = vrnode (Terrain_node,“孩子”,“Terrain_Shape”,“形状”);为形状创建外观字段newAppear = vrnode (newShape,“外观”,“Terrain_Appearance”,“外观”);为外观创建材质字段newMat = vrnode (newAppear,“材料”,“Terrain_Material”,“材料”);为材质字段分配属性newMat。ambientIntensity = 0.25;newMat。diffuseccolor = [0.9 0.6 0.6];newMat。亮度= 0.078125;newMat。speccolor = [0.0955906 0.0955906 0.0955906];%创建形状的几何字段newEGrid = vrnode (newShape,“几何”,“DEM_EGrid”,“ElevationGrid”);%为几何域分配属性-使用DEM数据newEGrid。creaseAngle = 3.14;newEGrid。xDimension = xdim;newEGrid。zDimension = zdim;newEGrid。xSpacing = xspace;newEGrid。zSpacing = zspace; newEGrid.height = demdata; newEGrid.ccw =“真正的”;这个设置将使地形表面从两边都可见newEGrid。固体=“假”;
为了给地形纹理着色,我们将使用Mapping Toolbox中的DEMCMAP函数。
%地形高程用于给图像着色cmap = demcmap(Z, 256);创建当前目录的纹理子目录%输出参数仅用于避免在目录%已经存在[~, ~] = mkdir(“纹理”);%比例的高度值,以使用完整的彩色地图范围%缩放依赖于地形从零高度开始的事实Zscaled = Z .* (size(cmap,1)-1) ./ max(Z(:));%在纹理子目录中将纹理保存为PNG图像%向左旋转图像以匹配X3D模型中所需的图像方向Zscaled中的%元素表示cmap中的索引imwrite (rot90 (Zscaled),提出,“纹理/ sanfrancisco_elev.png”);
纹理图像文件是由上面的代码创建的,这里它被包含在X3D场景中,作为地形Appearance节点的纹理场:
newTexture = vrnode (newAppear,“纹理”,“Terrain_texture”,“ImageTexture”);newTexture。url =“纹理/ sanfrancisco_elev.png”;
内联模型在sl3ddemo目录中。
因为文件使用相对路径进行内联,所以我们必须将它们复制到新创建的场景文件所在的同一个目录中。
如果你复制地形模型到一个不同的位置,不要忘记也复制这些文件,以及纹理文件,可以在纹理子目录中找到。
%本架飞机。X3d从/sl3ddemos到当前目录pt = fileparts ((“vrterrain_simple.m”));拷贝文件(fullfile (pt,“b747.x3d”pwd),“f”);
创建一个新的Transform节点,称为“Boeing”飞机= vrnode (myworld,“波音”,“转换”);plane_inline = vrnode(飞机,“孩子”,“Boeing_Inline”,“内联”);在/sl3ddemos目录中准备了一个简单的Boeing模型plane_inline.url =“b747.x3d”;
ypeak = max (Z (:));[xmax, zmax] = find(Z==ypeak);%如果更多的顶点具有相同的最大高度,则使用第一个峰值%转换矩阵指数到米在x和z方向在X3Dxpeak = xspace * (xmax (1) 1);zpeak = zspace * (zmax (1) 1);
飞机。翻译= [xpeak ypeak+200 zpeak];把这架飞机的尺寸按原来的20倍放大,这样就可以把飞机的尺寸缩小到原来的20倍%在虚拟场景中是可见的,不需要任何额外的缩放飞机。[20 20 20];
有时,在场景中临时加入一个三和弦是有用的,它可以帮助添加到场景中的对象的方向。Triad被简单地创建为位于“vrterrain_sanfrancisco”中的Triad EXTERNPROTO的实例。x3d”文件。
%三角形由3条线(1米长)从一个顶点开始沿着x, y, z方向。这些线的颜色如下:% +x -红色% +y -绿色% +z -蓝色%%如果这个三元组被包含在场景的顶层%层次结构,它表示全局场景坐标。%如果它作为转换节点的子节点包含,则表示本地场景中那个节点的坐标系统(方向)。%将三元组添加到场景的层次结构的顶层三和弦= vrnode (myworld,“Triad1”,“三位一体”);%缩放三位一体的大小,使其可见%在虚拟场景中,没有任何额外的缩放三合会。规模= [xdim*xspace/8 min(xdim*xspace/8, zdim*zspace/8)];将三角放置在波音747的中心三合会。位置= [xpeak ypeak + 200 zpeak];
改变场景的标题以反映我们所做的改变
myworld.World_Info。title =“B747飞越旧金山地区”;
保存(myworld,“vrterrain_sanfrancisco.x3d”);
关闭(myworld);删除(myworld);
有几个选择如何打开虚拟场景文件:
%这是如何在外部查看器中打开X3D文件:% vrview(“地形。x3d”、“网”);%这是如何在内部查看器中打开X3D文件:% vrview(“地形。x3d”、“内部”);%这是如何在默认查看器中打开X3D文件:createdworld = vrview (“vrterrain_sanfrancisco.x3d”);设置反锯齿以平滑地形纹理myfig =得到(createdworld,“数据”);集(myfig,抗锯齿的,“上”);
这个示例在工作目录中创建了一个新的虚拟模型。
新创建的虚拟场景是开放的,以便您可以探索它。
清除所有已使用的变量清晰的Terrain_nodeZZscaled提出createdworlddemFilenamedemdata前女友文件名...id纬度朗混乱myfigmyworldnewAppearnewEGrid...newMatnewShapenewTexture纳米好吧飞机plane_inlinept三合会...已经xdimxmaxxpeakxspaceypeakzdimzmaxzpeakzspace