2.6.9 相机操作
相机操作
相机操作是指调整场景相机参数的更新操作。可以通过相机操作更新相机的透视角大小、视野距离、近截面距离和天空盒路径等。
相机操作主要包括添加(创建)、更新和删除3种操作。
下图是相机操作效果:
参数说明
相机操作可配置的参数如下表所示:
配置项 | 配置说明 | 值类型 | 备注 |
---|---|---|---|
OptionsTypeName | 操作配置项类名 | string | CameraOptions代表相机操作 |
LodScale | 视野距离比例 | float | LOD模型加载的视野距离比例。该值越大,模型视野可见距离越小。默认:1.0 |
Fovy | 透视角 | float | 相机透视角。该值取值范围在5-179度之间。默认:35 |
NearPlane | 近平面距离 | double | 相机近平面距离。该值影响靠近相机位置数据的裁剪。默认会自动计算 |
SkyBoxImgPath | 天空盒路径 | string | 包含天空盒数据的路径。系统会自带星空的天空盒 |
IsAsFrustum | 是否开启局部放大功能 | bool | 是否开启局部放大功能。如果开启,则会使用ViewPoint 参数进行放大。如果关闭,则还原到开启之前视角状态。默认为false |
ViewPoint | 屏幕坐标 | left,right,bottom,top | 开启局部放大使用的屏幕坐标。 |
代码调用示例
Javascript调用
var event;
var left = 0;
var right = 0;
var top = 0;
var bottom = 0;
var operationPtr = null;
//回调实现函数
function callBackFun(x, y){
var result = operationPtr.GetOperationResult();
var MinFovy = result.GetConfigValueByKey("MinFovy");//最大透视角
var MaxFovy = result.GetConfigValueByKey("MaxFovy");//最小透视角
//若是使用了局部放大功能,以下参数传回的是放大前的相机参数
var Fovy = result.GetConfigValueByKey("Fovy");//相机透视角
var Aspect = result.GetConfigValueByKey("Aspect");//相机宽高比
var Znear = result.GetConfigValueByKey("Znear");//相机近截面
var Height = result.GetConfigValueByKey("Height");//相机高度
var Width = result.GetConfigValueByKey("Width");//相机宽度
alert("MinFovy:" + MinFovy + ";MaxFovy:" + MaxFovy);
}
//回调实现函数
function callBackFun1(str, id){
//alert("str:" + str + ";id:" + id);
var str2 = str.split("|");
if(str2[1] == "UIRectangleResponser" || str == "UIRectangleResponser")
{
responseStr = resRectangle.GetResponserResult().GetConfigValueByKey("Points");//获取点位
alert(responseStr);
var res = responseStr.split(";");
var str = res[0].split(",");
var str1 = res[1].split(",");
left = str[0];
right = str1[0];
bottom = str1[1];
top = str[1];
}
}
//创建相机操作对象
function CreateUpdateOperation(){
if(operationPtr == null){
event = addEvent(obj, "FireOnOperationNotify", callBackFun);//返回值用于IE11版本事件移除
var tlo = map.CreateOperationOptions("Camera");//创建更新配置对象,任意名称
tlo.AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo.AddConfig("LodScale", 1.0);//设置比例系数
operationPtr = map.CreateOperation("CameraOperation", tlo);//创建更新对象,CameraOperation代表相机更新
operationPtr.AddObserver()//添加监听事件
map.AddOperation(operationPtr);//加入操作并执行
}else{
alert("操作对象已存在,无需创建!");
}
}
//视野距离更新
function UpdateLodScale(){
if(operationPtr){
var tlo = map.CreateOperationOptions("Camera");//创建更新配置对象,任意名称
tlo.AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo.AddConfig("LodScale", 0.8);//设置比例系数
operationPtr.UpdateOperationOptions(tlo);//更新
}else{
alert("操作对象不存在,更新失败!");
}
}
//透视角更新
function UpdateFovy(){
if(operationPtr){
var tlo = map.CreateOperationOptions("Camera");//创建更新配置对象,任意名称
tlo.AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo.AddConfig("Fovy", 10);//设置透视角
operationPtr.UpdateOperationOptions(tlo);//更新
}else{
alert("操作对象不存在,更新失败!");
}
}
//天空盒路径
function UpdateSkyBoxImgPath(){
if(operationPtr){
var tlo = map.CreateOperationOptions("Camera");//创建更新配置对象,任意名称
tlo.AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo.AddConfig("SkyBoxImgPath", "E:\\Skybox\\");//天空盒路径
operationPtr.UpdateOperationOptions(tlo);//更新
}else{
alert("操作对象不存在,更新失败!");
}
}
//近平面更新
function UpdateNearPlane(){
if(operationPtr){
var tlo = map.CreateOperationOptions("Camera");//创建更新配置对象,任意名称
tlo.AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo.AddConfig("NearPlane", 10);//近平面距离
operationPtr.UpdateOperationOptions(tlo);//更新
}else{
alert("操作对象不存在,更新失败!");
}
}
var IsLocalAmplify = true;//局部放大开关
//局部放大
function UpdateLocalAmplify() {
var tlo = map.CreateOperationOptions("Camera");//创建配置类型,操作类型的配置
tlo.AddConfig("OptionsTypeName", "CameraOptions");
if(IsLocalAmplify)
{
tlo.AddConfig("IsAsFrustum", "true");//是否放大,true为放大操作,false为复原放大
}
else
{
tlo.AddConfig("IsAsFrustum", "false");//是否放大,true为放大操作,false为复原放大
}
if(left ===0 && right === 0 && bottom === 0 && top === 0)
{
alert("请先用矩形响应器进行放大位置设定!")
return;
}
tlo.AddConfig("ViewPoint", left+","+right+","+bottom+","+top);//局部放大屏幕坐标,左,右,下, 上
//tlo.AddConfig("ViewPoint", "500,600,200,600");//局部放大屏幕坐标,左,右,下, 上
operationPtr.UpdateOperationOptions(tlo);//根据配置创建模型调整操作
IsLocalAmplify = !IsLocalAmplify;
if(resRectangle)
{
map.RemoveResponser("UIRectangleResponser");//移除矩形响应器
resRectangle = null;
}
}
//移除操作
function RemoveOperation(){
if(operationPtr){
IsLocalAmplify = false;
UpdateLocalAmplify();//还原局部放大
map.RemoveOperation(operationPtr);//移除更新操作
operationPtr = null;
delEvent(obj, "FireOnFullScreenState", callBackFun, event);//第四个参数用于IE11事件删除,其他浏览器传null即可
}else{
alert("操作对象不存在,无需重复移除!");
}
}
//*************************************************************************
//矩形响应器
//*************************************************************************
var resRectangle;
//添加矩形响应器
function AddRectangle() {
var resp = map.CreateResponserOptions("UIRectangleResponser");//创建响应器配置
resp.AddConfig("LineColor", "0.0,0.0,1.0,1.0");//设置线的颜色
resp.AddConfig("LineWidth", "2");//线宽(0-10)
resp.AddConfig("IsDragMode", "false");//是否为拖拽模式,拖拽模式下,需要按住鼠标进行绘制,默认为false
//下列二个配置可选
//resp.AddConfig("IsLoad", "false");//是否预加载
//resp.AddConfig("Points", "500,600;600,200;");//屏幕坐标,以;结尾
resRectangle = map.CreateResponser("UIRectangleResponser", resp);//创建矩形响应器
map.AddResponser(resRectangle);//添加响应器
resRectangle.AddObserver();//开启事件回调
}
//修改矩形响应器
function ModifyRectangle() {
var resp = map.CreateResponserOptions("UIRectangleResponser");//创建响应器配置
resp.AddConfig("LineColor", "1.0,0.0,0.0,1.0");//设置线的颜色
resp.AddConfig("LineWidth", "2");//线宽(0-10)
//下列二个配置可选
resp.AddConfig("IsLoad", "true");//是否预加载
resp.AddConfig("Points", "500,600;600,200;");//屏幕坐标,以;结尾
resRectangle.UpdateResponserOptions(resp);
}
//移除矩形响应器
function RemoveRectangle() {
map.RemoveResponser("UIRectangleResponser");//移除矩形响应器
resRectangle = null;
}
C++调用
BaseObjectCOMLib::IOperationObjectPtr operationPtr;//更新对象
//创建相机操作对象
void Cf5c8CameraDlg::OnBnClickedCreateupdateoperation()
{
if(operationPtr)
{
return;
}
ConfigOptionsCOMLib::IOperationOptionPtr tlo = map->CreateOperationOptions("Camera");//创建配置类型,操作类型的配置
tlo->AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo->AddConfig("Operation", "LodScale");//操作类型
tlo->AddConfig("LodScale", "1.0");//设置比例系数
operationPtr = map->CreateOperation("CameraOperation", tlo);//创建更新对象,CameraOperation代表相机更新
map->AddOperation(operationPtr);//加入操作并执行
}
//视野距离设置
void Cf5c8CameraDlg::OnBnClickedUpdatelodscale()
{
if(!operationPtr)
{
return;
}
ConfigOptionsCOMLib::IOperationOptionPtr tlo = map->CreateOperationOptions("Camera");//创建配置类型,操作类型的配置
tlo->AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo->AddConfig("Operation", "LodScale");//操作类型
tlo->AddConfig("LodScale", "0.8");//设置比例系数
operationPtr->UpdateOperationOptions(tlo);//更新
}
//透视角设置
void Cf5c8CameraDlg::OnBnClickedUpdatefovy()
{
if(!operationPtr)
{
return;
}
ConfigOptionsCOMLib::IOperationOptionPtr tlo = map->CreateOperationOptions("Camera");//创建配置类型,操作类型的配置
tlo->AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo->AddConfig("Operation", "Fovy");//操作类型
tlo->AddConfig("Fovy", "10");//设置透视角
operationPtr->UpdateOperationOptions(tlo);//更新
}
//天空盒路径设置
void Cf5c8CameraDlg::OnBnClickedUpdateskyboximgpath()
{
if(!operationPtr)
{
return;
}
ConfigOptionsCOMLib::IOperationOptionPtr tlo = map->CreateOperationOptions("Camera");//创建配置类型,操作类型的配置
tlo->AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo->AddConfig("Operation", "SkyBoxImgPath");//操作类型
tlo->AddConfig("SkyBoxImgPath", "E:\\Skybox\\");//天空盒路径
operationPtr->UpdateOperationOptions(tlo);//更新
}
//近平面设置
void Cf5c8CameraDlg::OnBnClickedUpdatenearplane()
{
if(!operationPtr)
{
return;
}
ConfigOptionsCOMLib::IOperationOptionPtr tlo = map->CreateOperationOptions("Camera");//创建配置类型,操作类型的配置
tlo->AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo->AddConfig("Operation", "NearPlane");//操作类型
tlo->AddConfig("NearPlane", "10");//近平面距离
operationPtr->UpdateOperationOptions(tlo);//更新
}
bool IsLocalAmplify= true;
void Cf5c8CameraDlg::OnBnClickedUpdatelocalamplify()
{
ConfigOptionsCOMLib::IOperationOptionPtr tlo = map->CreateOperationOptions("Camera");//创建配置类型,操作类型的配置
tlo->AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
if(IsLocalAmplify)
{
tlo->AddConfig("IsAsFrustum", "true");//开启局部放大功能
}
else
{
tlo->AddConfig("IsAsFrustum", "false");//关闭局部放大,相机会回归放大前的视角
}
if(left =="0" && right == "0" && bottom == "0" && top == "0")
{
MessageBox(L"请先用矩形响应器进行放大位置设定!");
return;
}
tlo->AddConfig("ViewPoint", (left+","+right+","+bottom+","+top).c_str());//局部放大屏幕坐标,左,右,下, 上
//tlo->AddConfig("ViewPoint", "500,600,200,600");//局部放大屏幕坐标,左,右,下, 上
operationPtr->UpdateOperationOptions(tlo);//根据配置创建模型调整操作
IsLocalAmplify = !IsLocalAmplify;
if(resRectangle)
{
map->RemoveResponser("UIRectangleResponser");//移除矩形响应器
resRectangle = NULL;
}
}
//移除操作
void Cf5c8CameraDlg::OnBnClickedRemoveoperation()
{
if(!operationPtr)
{
return;
}
map->RemoveOperation(operationPtr);
operationPtr = NULL;
}
void Cf5c8CameraDlg::OnBnClickedAddrectangle()
{
AddRectangle();
}
void Cf5c8CameraDlg::OnBnClickedModifyrectangle()
{
ModifyRectangle();
}
void Cf5c8CameraDlg::OnBnClickedRemoverectangle()
{
RemoveRectangle();
}
//*************************************************************************
//矩形响应器
//*************************************************************************
//添加矩形响应器
void Cf5c8CameraDlg::AddRectangle() {
ConfigOptionsCOMLib::IResponserOptionPtr resp = map->CreateResponserOptions("UIRectangleResponser");
resp->AddConfig("LineColor", "0.0,0.0,1.0,1.0");//设置线的颜色
resp->AddConfig("LineWidth", "2");//设置线宽,1~10
resp->AddConfig("IsDragMode", "false");//是否为拖拽模式,拖拽模式下,需要按住鼠标进行绘制,默认为false
//下列二个配置可选
//resp->AddConfig("IsLoad", "false");//是否预加载
//resp->AddConfig("Points", "500,600;600,200;");//屏幕坐标,以;结尾
resRectangle = map->CreateResponser("UIRectangleResponser", resp);//
map->AddResponser(resRectangle);
resRectangle->AddObserver();//开启事件回调
}
//修改矩形响应器
void Cf5c8CameraDlg::ModifyRectangle() {
ConfigOptionsCOMLib::IResponserOptionPtr resp = map->CreateResponserOptions("UIRectangleResponser");
resp->AddConfig("LineColor", "1.0,0.0,0.0,1.0");//设置线的颜色
resp->AddConfig("LineWidth", "4");//设置线宽,1~10
//下列二个配置可选
resp->AddConfig("IsLoad", "true");//是否预加载
resp->AddConfig("Points", "500,600;600,200;");//屏幕坐标,以;结尾
resRectangle->UpdateResponserOptions(resp);
}
//移除矩形响应器
void Cf5c8CameraDlg::RemoveRectangle() {
map->RemoveResponser("UIRectangleResponser");//移除矩形响应器
resRectangle = NULL;
}
BEGIN_EVENTSINK_MAP(Cf5c8CameraDlg, CDialogEx)
ON_EVENT(Cf5c8CameraDlg, IDC_VPSDKCTRL1, 15, Cf5c8CameraDlg::FireOnResponserNotifyVpsdkctrl1, VTS_BSTR VTS_I4)
END_EVENTSINK_MAP()
void Cf5c8CameraDlg::FireOnResponserNotifyVpsdkctrl1(LPCTSTR respType, long notifyType)
{
ConfigOptionsCOMLib::IResponserOptionPtr respOpt = resRectangle->GetResponserResult();
std::string responseStr = respOpt->GetConfigValueByKey("Points");//获取点位
std::vector<std::string> res,str,str1;
SplitString(responseStr,res,";");
SplitString(res[0],str,",");
SplitString(res[1],str1,",");
left = str[0];
right = str1[0];
bottom = str1[1];
top = str[1];
}
void Cf5c8CameraDlg::SplitString(const std::string& s,std::vector<std::string>& v,const std::string& c)
{
std::string::size_type pos1,pos2;
pos2 = s.find(c);
pos1 = 0;
while(std::string::npos !=pos2)
{
v.push_back(s.substr(pos1,pos2-pos1));
pos1 = pos2 + c.size();
pos2= s.find(c,pos1);
}
if(pos1 !=s.length())
{
v.push_back(s.substr(pos1));
}
}
C#调用
IOperationObject operationPtr;
//创建相机操作对象
private void CreateUpdateOperation_Click(object sender, EventArgs e)
{
if(operationPtr == null){
var tlo = map.CreateOperationOptions("Camera");//创建更新配置对象,任意名称
tlo.AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo.AddConfig("Operation", "LodScale");//操作类型
tlo.AddConfig("LodScale", 1.0);//设置比例系数
operationPtr = map.CreateOperation("CameraOperation", tlo);//创建更新对象,CameraOperation代表相机更新
operationPtr.AddObserver();//添加监听事件
map.AddOperation(operationPtr);//加入操作并执行
}else{
MessageBox.Show("操作对象已存在,无需创建!");
}
}
//视野距离更新
private void UpdateLodScale_Click(object sender, EventArgs e)
{
if (operationPtr!=null)
{
var tlo = map.CreateOperationOptions("Camera");//创建更新配置对象,任意名称
tlo.AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo.AddConfig("Operation", "LodScale");//操作类型
tlo.AddConfig("LodScale", 0.8);//设置比例系数
operationPtr.UpdateOperationOptions(tlo);//更新
}
else
{
MessageBox.Show("操作对象不存在,更新失败!");
}
}
//透视角更新
private void UpdateFovy_Click(object sender, EventArgs e)
{
if (operationPtr!=null)
{
var tlo = map.CreateOperationOptions("Camera");//创建更新配置对象,任意名称
tlo.AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo.AddConfig("Operation", "Fovy");//操作类型
tlo.AddConfig("Fovy", "0");//设置透视角
operationPtr.UpdateOperationOptions(tlo);//更新
}
else
{
MessageBox.Show("操作对象不存在,更新失败!");
}
}
//天空盒路径
private void UpdateSkyBoxImgPath_Click(object sender, EventArgs e)
{
if (operationPtr!=null)
{
var tlo = map.CreateOperationOptions("Camera");//创建更新配置对象,任意名称
tlo.AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo.AddConfig("Operation", "SkyBoxImgPath");//操作类型
tlo.AddConfig("SkyBoxImgPath", "E:\\Skybox\\");//天空盒路径
operationPtr.UpdateOperationOptions(tlo);//更新
}
else
{
MessageBox.Show("操作对象不存在,更新失败!");
}
}
//近平面更新
private void UpdateNearPlane_Click(object sender, EventArgs e)
{
if (operationPtr!=null)
{
var tlo = map.CreateOperationOptions("Camera");//创建更新配置对象,任意名称
tlo.AddConfig("OptionsTypeName", "CameraOptions");//更新类型,CameraOptions代表相机更新
tlo.AddConfig("Operation", "NearPlane");//操作类型
tlo.AddConfig("NearPlane", 10);//近平面距离
operationPtr.UpdateOperationOptions(tlo);//更新
}
else
{
MessageBox.Show("操作对象不存在,更新失败!");
}
}
//移除操作
private void RemoveOperation_Click(object sender, EventArgs e)
{
if(operationPtr!=null){
map.RemoveOperation(operationPtr);
operationPtr = null;
}else{
MessageBox.Show("操作对象不存在,无需重复移除!");
}
}
string left = "0";
string right = "0";
string top = "0";
string bottom = "0";
bool IsLocalAmplify = true;
private void UpdateLocalAmplify_Click(object sender, EventArgs e)
{
var tlo = map.CreateOperationOptions("Camera");//创建配置类型,操作类型的配置
tlo.AddConfig("OptionsTypeName", "CameraOptions");
if(IsLocalAmplify)
{
tlo.AddConfig("IsAsFrustum", "true");
}
else
{
tlo.AddConfig("IsAsFrustum", "false");
}
if(left =="0" && right == "0" && bottom == "0" && top == "0")
{
MessageBox.Show("请先用矩形响应器进行放大位置设定!");
return;
}
tlo.AddConfig("ViewPoint", left+","+right+","+bottom+","+top);//局部放大屏幕坐标,左,右,下, 上
//tlo.AddConfig("ViewPoint", "500,600,200,600");//局部放大屏幕坐标,左,右,下, 上
operationPtr.UpdateOperationOptions(tlo);//根据配置创建模型调整操作
IsLocalAmplify = !IsLocalAmplify;
if(resRectangle != null)
{
map.RemoveResponser("UIRectangleResponser");//移除矩形响应器
resRectangle = null;
}
}
//*************************************************************************
//矩形响应器
//*************************************************************************
IResponserObject resRectangle;
//添加矩形响应器
private void AddRectangle()
{
var resp = map.CreateResponserOptions("UIRectangleResponser");
resp.AddConfig("LineColor", "0.0,0.0,1.0,1.0");//设置线的颜色
resp.AddConfig("LineWidth", "2");//设置线宽,1~10
resp.AddConfig("IsDragMode", "false");//是否为拖拽模式,拖拽模式下,需要按住鼠标进行绘制,默认为false
//下列二个配置可选
//resp.AddConfig("IsLoad", "false");//是否预加载
//resp.AddConfig("Points", "500,600;600,200;");//屏幕坐标,以;结尾
resRectangle = map.CreateResponser("UIRectangleResponser", resp);//
map.AddResponser(resRectangle);
resRectangle.AddObserver();//开启事件回调
}
//修改矩形响应器
private void ModifyRectangle()
{
var resp = map.CreateResponserOptions("UIRectangleResponser");
resp.AddConfig("LineColor", "1.0,0.0,0.0,1.0");//设置线的颜色
resp.AddConfig("LineWidth", "4");//设置线宽,1~10
//下列二个配置可选
resp.AddConfig("IsLoad", "true");//是否预加载
resp.AddConfig("Points", "500,600;600,200;");//屏幕坐标,以;结尾
resRectangle.UpdateResponserOptions(resp);
}
//移除矩形响应器
private void RemoveRectangle()
{
map.RemoveResponser("UIRectangleResponser");//移除矩形响应器
resRectangle = null;
}
private void axVPSDKCtrl1_FireOnResponserNotify(object sender, AxSDKCtrlLib._IVPSDKCtrlEvents_FireOnResponserNotifyEvent e)
{
string responseStr = resRectangle.GetResponserResult().GetConfigValueByKey("Points");//获取点位
MessageBox.Show(responseStr);
var res = responseStr.Split(';');
var str = res[0].Split(',');
var str1 = res[1].Split(',');
left = str[0];
right = str1[0];
bottom = str1[1];
top = str[1];
}