unigine objectglobleterrain

28 篇文章 6 订阅
//render  height out
if (App::get()->clearMouseButtonState(App::BUTTON_LEFT))
	{
		Vec3 pos = Game::get()->getPlayer()->getWorldPosition();
		vec3 dir = Game::get()->getPlayer()->getDirectionFromScreen();//拿到方向
		double zfar = Game::get()->getPlayer()->getZFar();//拿到相机渲染的最长长度
		Vec3 outPos;
		GlobalPivot::get()->getIntersection(pos, pos + Vec3(dir)*zfar, outPos);//GlobalPivot是自定义的类,封装了geopivot对象和globalterrain对象,获取到与地形相交的点位置
		Vec3 flatPos = GlobalPivot::get()->mapToFlat(translate(outPos));//将位置转为平铺坐标,这里有三种坐标请看其他博客
		float size = GlobalPivot::get()->getHeightTileSize();
		ivec2 c = ivec2((int)Math::floor(flatPos.x / size), (int)Math::floor((flatPos.y / size)));
		worldPos = outPos;
		if (coord != c) {
			coords.clear();
			coord = c;
			GlobalPivot::get()->getTerrainHeightImage(c, timg);
			flatPos.x = c.x*size;
			flatPos.y = c.y*size;
			flatPos.z = timg->get2D(0, 0).f.r;
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					GlobalPivot::get()->getWorldPos(Vec3(flatPos.x + i/128.0*size, flatPos.y + j / 128.0*size, timg->get2D(i, j).f.r), pos);
					coords.append(pos);
				}
			}
		}
	}
	for (int i = 0; i < coords.size(); i++)
	{
		Visualizer::get()->renderSphere(1, translate(coords[i]), vec4(1, 0, 0, 1));
	}

ObjectTerrainGlobal是由如下几部分组装的:

virtual Ptr<TerrainGlobalLods> getHeightLods() = 0;
 virtual Ptr<TerrainGlobalLods> getAlbedoLods() = 0;
 virtual Ptr<TerrainGlobalLods> getNormalLods() = 0;
 virtual Ptr<TerrainGlobalLods> getMaskLods() = 0;

每部分数据有多个lod
virtual const char *getName() const = 0;
    virtual int getType() const = 0;
    virtual int getDataType() const = 0;
    virtual int getDataFormat() const = 0;
    virtual int getMaskFormat() const = 0;
    virtual void setNumLayers(int layers) = 0;
    virtual int getNumLayers() const = 0;
    virtual int getNumLods() const = 0;
    virtual Ptr<TerrainGlobalLod> getLod(int num) const = 0;
    virtual int addLod() = 0;
    virtual void insertLod(int num) = 0;
    virtual void removeLod(int num) = 0;
    virtual void clearLods() = 0;
    virtual String getVideoMemoryUsage() const = 0;
    virtual int fetch(const BoundSphere & bs, const BoundBox & bb, int force = 0) = 0;
    virtual int fetchData(double x, double y, Image::Pixel &ret_pixel, int layer, bool force) = 0;
每一个lof可以获取tileset(记录了地形的原始数据)
    virtual Ptr<TerrainGlobalLod> getTerrainGlobalLod() const = 0;
    virtual void setEnabled(int enabled) = 0;
    virtual int isEnabled() const = 0;
    virtual Ptr<Tileset> getTileset() const = 0;
    virtual void setPath(const char *path) = 0;
    virtual const char *getPath() const = 0;
    virtual int renamePath(const char *new_path) = 0;
    virtual void setTileDensity(float density) = 0;
    virtual float getTileDensity() const = 0;
    virtual void setViewportMask(int mask) = 0;
    virtual int getViewportMask() const = 0;
    virtual void setVisibleDistance(float distance) = 0;
    virtual float getVisibleDistance() const = 0;
    virtual void setLoadDistance(float distance) = 0;
    virtual float getLoadDistance() const = 0;
    virtual void setClearDistance(float distance) = 0;
    virtual float getClearDistance() const = 0;
    virtual void reload() = 0;

	ObjectTerrainGlobalPtr terrain = ObjectTerrainGlobal::cast(Editor::get()->getNodeByName("Landscape"));
	Vec3 rp;
	vec3 normal, up;
	terrain->fetchTopologyData(0, 0, rp, normal, up);
	TilesetPtr tile = terrain->getHeightLods()->getLod(0)->getTileset();
	float size = tile->getTileSize();//一张图像描述的大小,米为单位
	int re = tile->getTileResolution();//图像的分辨率 一般是128
	Vec2 p = tile->getTileFlatPosition(ivec2(0, 0));//获取该坐标为0,0的图像0,0的flat坐标
	int t = tile->hasTile(ivec2(10, 10));
	p = tile->getTileFlatPosition(ivec2(10, 10)); 
	t = tile->hasTile(ivec2(128, 129));
	p = tile->getTileFlatPosition(ivec2(128,129));
	for (int i = 0; i < terrain->getAlbedoLods()->getNumLods(); i++)
	{
		tile = terrain->getAlbedoLods()->getLod(i)->getTileset();
		size = tile->getTileSize();
		re = tile->getTileResolution();
		float d = terrain->getAlbedoLods()->getLod(i)->getVisibleDistance();
		float de = terrain->getAlbedoLods()->getLod(i)->getTileDensity();
		Log::message("%f,%d,%f,%f,%f\n", size, re,d,de,size/re);
	}
	Log::message("h:\n");
	for (int i = 0; i < terrain->getHeightLods()->getNumLods(); i++)
	{
		tile = terrain->getHeightLods()->getLod(i)->getTileset();
		size = tile->getTileSize();
		re = tile->getTileResolution();
		float d = terrain->getHeightLods()->getLod(i)->getVisibleDistance();
		float de = terrain->getHeightLods()->getLod(i)->getTileDensity();  //密度,等于size/re
		Log::message("%f,%d,%f,%f,%f\n", size, re, d, de, size / re);
	}
	ObjectTerrainGlobalPtr terrain = ObjectTerrainGlobal::cast(Editor::get()->getNodeByName("Landscape"));
	testPos = terrain->getWorldPosition();
	TilesetPtr tiles = terrain->getHeightLods()->getLod(0)->getTileset();
	ImagePtr data = Image::create();
	tiles->getTileData(ivec2(0, 0),data,1);
	Vec3 wpos;
	vec3 normal, up;
	terrain->fetchTopologyData(0, 0, wpos, normal, up,1);  //从terrian pos 
	GlobalPivot::get()->getWorldPos(wpos, testPos1);
	terrain->fetchTopologyData(0, 10, wpos, normal, up, 1);
	GlobalPivot::get()->getWorldPos(wpos, testPos2);
	terrain->fetchTopologyData(10, 0, wpos, normal, up, 1);
	GlobalPivot::get()->getWorldPos(wpos, testPos3);
	Image::Pixel p = data->get2D(0, 0);
	Log::message("r:%f\n", p.f.r);
	testPos.z = p.f.r;  //set the pos
	
	tiles->setTileData(ivec2(0,0),timg); //当镜头转向后可能会被替换回来。
	tiles->setLifeTime(ivec2(0, 0),10000 );//设置完后立马设置时间

	
	int count = 0;
	int ii = 0, jj=0; //获取tile的数量
	for (int i = 0;; i++)  //
	{
		bool havedata = false;
		for (int j = 0;; j++)
		{
			if (tile->hasTile(ivec2(i, j)))
			{
				count++;
				havedata = true;
			}
			else
			{
				if (jj < j) jj = j;
				break;
			}
		}
		if (!havedata)
		{
			if(ii<i) ii = i;
			break;
		}
	}
	count = ii*2*jj*2;  //coordinate index range(-ii ~ ii , -jj ~ jj)
	
	
	float size = tile->getTileSize(); //一张图片表示的实际大小
	int re = tile->getTileResolution();//一张图片的分辨率
	Vec2 p = tile->getTileFlatPosition(ivec2(0, 0)); //从纹理坐标转flat坐标
	tile->getTileData(ivec2(10, 10), img); //获取tile,ivec需有效
	
	
	Vec2 size = GlobalPivot::get()->getTSize();//(5786.2423553466797*2, 6453.8857040405273*2)  //terrainsize
	ivec2 isize = GlobalPivot::get()->getSize();  //(78*2,87*2) //terrain tilecount
	Vec3 pos;
	vec3 up, normal;
	double t = Timer::getFloatTime();
	for (int i = 0; i < 1000; i++)  //time cost
	{
		//terrain->fetchTopologyData(Game::get()->getRandomDouble(-size.x, size.x), Game::get()->getRandomDouble(-size.y, size.y), pos, normal, up, 1); //1.64~2s
		//terrain->fetchTopologyData(Game::get()->getRandomDouble(-1,1), Game::get()->getRandomDouble(-1,1),pos,normal,up,1);// 16~18 ms
		terrain->fetchTopologyData(Game::get()->getRandomDouble(-100, 100), Game::get()->getRandomDouble(-100, 100), pos, normal, up, 1); //16~18ms
	}
	t = Timer::getFloatTime() - t;
	
	地形坐标系与实际经纬度对齐问题
	2.7.3中地形坐标系默认是在地形中心无高程的位置。从上面可以看出其tile的分布。如果没有高程数据也不使用geopivot,
那么地形中心刚好是地形坐标系的中心。加上高程后。会取对应位置的高程的高度,地形的坐标系位置在高度上也会偏离这个距离。
所以如果需要让现实坐标与场景的geodetic坐标对齐:首先让地形坐标系与pivot节点在同一个位置,找到地形中心对应的经纬度值,
设置geopivotaltitude 为地形中心点altitude 的负值。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值