2.5.5 室内漫游
室内漫游
室内漫游是指模拟在室内浏览、并且不会出现穿墙效果的漫游模式。它通过使用碰撞检测功能来保证漫游时不会出现穿墙效果的。 在使用室内漫游时,主要有以下几步操作:
- 添加挡板图层。 挡板图层是指用于作为碰撞检测的目标对象。一般来说它会是一份全透明的模型数据,这份数据中包含了室内数据中的大部分部件,尤其是墙体、门等部件。
- 进入室内。 通过飞行定位或者直接拖动场景进入室内场景。优先进入室内是为了防止开启室内漫游后,无法再进入室内的状况。
- 开启室内漫游。 调用SetInDoorRoamMode()接口进入室内漫游模式,该接口的第一个参数是开启状态,第二个参数为挡板图层ID。
- 室内漫游。 可以通过鼠标/键盘操作室内漫游,在前进的方向如果有墙等物体阻碍,将无法继续前进。
- 关闭室内漫游。 调用SetInDoorRoamMode()接口进入室内漫游模式,该接口的第一个参数是开启状态,第二个参数为挡板图层ID。
- 移除挡板图层。 关闭室内漫游后,需要手动移除挡板图层,否则会一直存在场景中。
下图是开启室内漫游的效果:
代码调用示例
Javascript调用
var baffleLayer = null;//挡板图层
//创建室内模型图层
function createIndoorLayer(){
var indoorLayer = loadModelLayer(gModelIndoorPath, "true", false);
}
//创建挡板图层,用于室内漫游碰撞检测
function createBaffleLayer(){
if(baffleLayer == null){
baffleLayer = loadModelLayer(gBafflePath, "true", false);
}else{
alert("请勿重复创建挡板图层!");
}
}
//定位至室内并打开室内模式
function locateLayerAndOpenIndoorRoam(){//为了更好地进入室内漫游,先定位至室内
var navigation = map.CreateNavigation();//创建漫游对象
var desP = map.CreatePosition(120.218360866, 30.2102196798, 15.4588537607);//创建坐标对象
navigation.FlyToDest(desP, 2.69883553453132, -0.1549291129273009, 12.42770649076648, 1);//飞行定位。坐标、旋转角、俯仰角、距离、飞行时间
setTimeout('openIndoorRoam()', 1200);//延时参数要比飞行时间大
}
//删除模型图层
function removeBaffleLayer(){
if(baffleLayer){
map.RemoveLayer(baffleLayer);//移除图层
baffleLayer = null;
}else{
alert("无挡板图层,无需移除!");
}
}
//打开室内漫游模式
function openIndoorRoam(){
if(baffleLayer == null){
alert("进入室内漫游模式时,需绑定指定的挡板图层,请加载挡板图层后重试!");
return;
}
var roam = map.CreateRoam();
roam.SetInDoorRoamMode(true, baffleLayer.GetLayerID());//参数二为挡板图层的id
}
//关闭室内漫游模式
function closeIndoorRoam(){
if(baffleLayer == null){
alert("退出室内漫游模式时,其绑定的挡板图层不能为空,请加载挡板图层后重试!");
return;
}
var roam = map.CreateRoam();
roam.SetInDoorRoamMode(false, baffleLayer.GetLayerID());//参数二为挡板图层的id
}
//加载模型图层
function loadModelLayer(url, compress, isLocate){
var tlo = map.CreateLayerOptions("modelOpt");//创建图层配置对象,任意名称
tlo.AddConfig("LayerOptionsName", "ModelLayerOptions");//图层配置对象名称, ModelLayerOptions代表模型图层配置对象
if(url.indexOf('http') === -1){//判断url是本地路径还是服务路径,以便调用不同数据源来加载
tlo.AddConfig("DataSourceTypeName", "c3s");//数据源类型,c3s代表本地数据源
}else{
tlo.AddConfig("DataSourceTypeName", "c3ss");//数据源类型,c3ss代表服务数据源
}
tlo.AddConfig("Compress", compress);//支持压缩和未压缩数据(根据数据实际情况设置),一般情况下均未压缩数据
tlo.AddConfig("Url", url);//数据路径
var modelLayer = map.CreateLayer("ModelLayer", tlo);//创建模型图层,第一项参数为ModelLayer
map.AddLayer(modelLayer);//添加图层
if(isLocate){
modelLayer.Locate();//图层定位
}
return modelLayer;
}
C++调用
BaseObjectCOMLib::ILayerObjectPtr baffleLayer;//隐形挡板图层对象
//创建隐形挡板图层
void Cf4c4IndoorRoamDlg::OnBnClickedcreatebafflelayer()
{
if(!baffleLayer)
{
char temp_status[MAX_PATH];
GetPrivateProfileStringA("Path", "BafflePath", "", temp_status, MAX_PATH, mIniPath.c_str());
std::string BafflePath(temp_status);
baffleLayer = loadModelLayer(BafflePath, "true", false);
}
}
//删除隐形挡板图层
void Cf4c4IndoorRoamDlg::OnBnClickedremovebafflelayer()
{
if(baffleLayer){
map->RemoveLayer(baffleLayer);//移除图层
baffleLayer = NULL;
}
}
//打开室内漫游模式
void Cf4c4IndoorRoamDlg::OnBnClickedlocatelayerandopenindoorroam()
{
if(baffleLayer == NULL)
{
std::cout << "进入室内漫游模式时,需绑定指定的挡板图层,请加载挡板图层后重试!" << std::endl;
return;
}
NavigationCOMLib::INavigatePtr navigation = map->CreateNavigation();//创建漫游对象
BaseObjectCOMLib::IPositionPtr desP = map->CreatePosition(120.218360866, 30.2102196798, 15.4588537607);//创建坐标对象
navigation->FlyToDest(desP, 2.69883553453132, -0.1549291129273009, 12.42770649076648, 1);//飞行定位。坐标、旋转角、俯仰角、距离、飞行时间
Sleep(1200);
std::stringstream stream;
stream << baffleLayer->GetLayerID();
NavigationCOMLib::IRoamPtr roam = map->CreateRoam();
roam->SetInDoorRoamMode(true, stream.str().c_str());//参数二为挡板图层的id
}
//关闭室内漫游模式
void Cf4c4IndoorRoamDlg::OnBnClickedcloseindoorroam()
{
if(baffleLayer == NULL){
std::cout << "退出室内漫游模式时,其绑定的挡板图层不能为空,请加载挡板图层后重试!" << std::endl;
return;
}
std::stringstream stream;
stream << baffleLayer->GetLayerID();
NavigationCOMLib::IRoamPtr roam = map->CreateRoam();
roam->SetInDoorRoamMode(false, stream.str().c_str());//参数二为挡板图层的id
}
//加载模型图层
BaseObjectCOMLib::ILayerObjectPtr Cf4c4IndoorRoamDlg::loadModelLayer(std::string url, std::string compress,BOOL isLocate)
{
ConfigOptionsCOMLib::ILayerOptionsPtr tlo = (ConfigOptionsCOMLib::ILayerOptionsPtr)map->CreateLayerOptions("modelOpt"); //创建图层配置对象,任意名称
tlo->AddConfig("LayerOptionsName", "ModelLayerOptions");//图层配置对象名称, ModelLayerOptions代表模型图层配置对象
if(!url.find("http"))//判断是否网络加载
{
tlo->AddConfig("DataSourceTypeName", "c3ss");//数据源类型,c3ss代表服务数据源
}
else
{
tlo->AddConfig("DataSourceTypeName", "c3s"); //数据源类型,c3s代表本地数据源
}
tlo->AddConfig("Url", url.c_str()); //数据路径
tlo->AddConfig("PriorityOffset","1.0");//结点调度优先级的偏移值
tlo->AddConfig("Compress", compress.c_str()); //是否压缩(根据数据实际情况设置)
BaseObjectCOMLib::ILayerObjectPtr modelLayer = (BaseObjectCOMLib::ILayerObjectPtr)map->CreateLayer("ModelLayer", tlo); ////创建模型图层,第一项参数必须为ModelLayer
map->AddLayer(modelLayer); ///添加模型图层
if(isLocate)//判断是否定位
{
modelLayer->Locate(); ////模型图层定位
}
return modelLayer;//返回模型图层
}
C#调用
ILayerObject baffleLayer;//隐形挡板对象
//创建挡板图层,用于室内漫游碰撞检测
private void createBaffleLayer_Click(object sender, EventArgs e)
{
var tlo = map.CreateLayerOptions("modelOpt");//创建图层配置对象,任意名称
tlo.AddConfig("LayerOptionsName", "ModelLayerOptions");//图层配置对象名称, ModelLayerOptions代表模型图层配置对象
tlo.AddConfig("DataSourceTypeName", "c3ss");//数据源类型,c3ss代表服务数据源
tlo.AddConfig("Compress", "true");//支持压缩和未压缩数据(根据数据实际情况设置),一般情况下均未压缩数据
tlo.AddConfig("Url", "http://192.168.1.50:8088/files/CooRunSDKDemoApplication-V6.1/data/Model/BaffleF1/0.c3s.zip");//数据路径
baffleLayer = map.CreateLayer("ModelLayer", tlo);//创建模型图层,第一项参数为ModelLayer
map.AddLayer(baffleLayer);//添加图层
}
//删除挡板图层
private void removeBaffleLayer_Click(object sender, EventArgs e)
{
if (baffleLayer != null)
{
map.RemoveLayer(baffleLayer);//移除图层
baffleLayer = null;
}
else
{
MessageBox.Show("无挡板图层,无需移除!");
}
}
//进入室内漫游
private void locateLayerAndOpenIndoorRoam_Click(object sender, EventArgs e)
{
var navigation = map.CreateNavigation();//创建漫游对象
var desP = map.CreatePosition(120.218360866, 30.2102196798, 15.4588537607);//创建坐标对象
navigation.FlyToDest(desP, 2.69883553453132, -0.1549291129273009, 12.42770649076648, 1);//飞行定位。坐标、旋转角、俯仰角、距离、飞行时间
Thread.Sleep(1200);//延时参数要比飞行时间大
if (baffleLayer == null)
{
MessageBox.Show("进入室内漫游模式时,需绑定指定的挡板图层,请加载挡板图层后重试!");
return;
}
var roam = map.CreateRoam();
roam.SetInDoorRoamMode(true, baffleLayer.GetLayerID());//参数二为挡板图层的id
}
//关闭室内漫游模式
private void closeIndoorRoam_Click(object sender, EventArgs e)
{
if (baffleLayer == null)
{
MessageBox.Show("退出室内漫游模式时,其绑定的挡板图层不能为空,请加载挡板图层后重试!");
return;
}
var roam = map.CreateRoam();
roam.SetInDoorRoamMode(false, baffleLayer.GetLayerID());//参数二为挡板图层的id
}