【二次开发】CityMaker几何体——模型

本文介绍了CityMaker中创建三维模型的技术原理,包括模型由模型符号和纹理组成,详细讲解了如何通过.NET和JS创建模型,以及注意事项,如顶点数组和纹理数组的对应规则,模型加载方式等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

**

三维中创建模型

**

一:技术原理

CityMaker模型点modelpoint是由模型符号(model)和纹理(image)组成,image可以是本地图片也可以是FDB纹理库中的图片,model可以是自己创建或者是用osg文件获取,一般情况model中由顶点数组、纹理数组、材质组成,通过顶点数组和纹理数组来描述模型和纹理规则
接口:createGeometry、createRenderModelPoint
方法:一种通过本地文件生成模型,二种是把模型和纹理添加到FDB或者内存中,三种是自己绘制顶点数组纹理数组通过文件贴图创建模型
在这里插入图片描述

二:创建模型

1. .NET

 public void createModelpoint(){
	//1.根据本地文件,获取model和image,创建模型
    IGeometryFactory gFactory = new GeometryFactory();
    IResourceFactory resFactory = new ResourceFactory();

    var modelPath = "D:\\citymakerbookdata\\Car\\TCJ006.osg";//设置模型
    var modelPoint = (IModelPoint)gFactory.CreateGeometry(gviGeometryType.gviGeometryModelPoint,gviVertexAttribute.gviVertexAttributeZ);
    modelPoint.ModelName = modelPath;
    modelPoint.SetCoords(100,100,100,0,0);
    var rModlePoint = rendercontrol.ObjectManager.CreateRenderModelPoint(modelPoint,null,__rootId);
    rendercontrol.Camera.FlyToObject(rModlePoint.Guid,0);

   //2.根据数据集中模型库和纹理库创建模型 
   //2-1先把模型和纹理添加到模型库和纹理库或者添加到内存中,通过程序或者builder
   var modelPath = "D:\\citymakerbookdata\\Car\\TCJ006.osg";
   IModel model=null;
   IMatrix matrix = null;
   IPropertySet proSet=null;
   resFactory.CreateModelAndImageFromFile(modelPath, out proSet, out model, out matrix);
   if (model == null || model.GroupCount == 0)
       return;
   var modelName = "TCJ006";

   //模型添加内存
   rendercontrol.ObjectManager.AddModel(modelName,model);
   var count = proSet.Count;
   if (count > 0) {
       var imageNames = proSet.GetAllKeys();
       for (var i = 0; i < count; i++)
       {
           var imageName = imageNames[i];
           var img = proSet.GetProperty(imageName);
           //贴图添加到内存
           rendercontrol.ObjectManager.AddImage(imageName, img);
       }
   }

   //2-2创建模型
   var modelPoint = (IModelPoint)gFactory.CreateGeometry(gviGeometryType.gviGeometryModelPoint, gviVertexAttribute.gviVertexAttributeZ);
   modelPoint.ModelName = modelName;
   modelPoint.SetCoords(100, 100, 100, 0, 0);
   var rModlePoint = rendercontrol.ObjectManager.CreateRenderModelPoint(modelPoint, null, __rootId);
   rendercontrol.Camera.FlyToObject(rModlePoint.Guid, 0);

   //3、自己绘制模型,通过一张图片贴图
   IModel model = resFactory.CreateModel();
   IImage image = resFactory.CreateImageFromFile("D:\\citymakerbookdata\\point.png");
   var imageName = "1";
   rendercontrol.ObjectManager.AddImage(imageName, image);

   //创建绘制组和绘制单元
   IDrawGroup group = new DrawGroup();
   IDrawPrimitive primitive = new DrawPrimitive();
   //顶点数组   不用索引数组的情况下  顶点坐标 xyz格式 逆时针
   IFloatArray vertexArray = new FloatArray();
   float[] varray = new float[] { 0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 0, 0, 10, 10, 0, 0, 10, 0, 0, 0, 0, 10, 0, 10, 0, 0, 10, 0, 0, 0, 10, 0, 0, 10, 0, 10, 10, 0, 0, 10, 10, 0, 10, 10, 10, 10, 0, 0, 10, 10, 10, 10, 0, 10, 10, 10, 0, 0, 10, 0, 0, 10, 10, 10, 10, 0, 0, 10, 10, 10, 10, 10, 0, 10, 0, 0, 0, 0, 0, 0, 10, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0, 0, 10, 10, 0, 10, 10, 10, 10, 0, 0, 10, 10, 10, 10, 0, 10, 10 };
   vertexArray.Array = varray;
   primitive.VertexArray = vertexArray;
   //纹理坐标 uv格式  纹理坐标跟顶点坐标是一一对应
   IFloatArray texcoordArray = new FloatArray();
   texcoordArray.Array = new float[] { 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1 };
   primitive.TexcoordArray = texcoordArray;

   //设置材质
   IDrawMaterial drawMaterial = new DrawMaterial();
   drawMaterial.DiffuseColor = 0xFF1093ED; //漫反射颜色
   drawMaterial.EnableLight = true; //开启光照
   drawMaterial.CullMode = gviCullFaceMode.gviCullNone; //双面显示
   drawMaterial.TextureName = imageName;
   drawMaterial.WrapModeS = gviTextureWrapMode.gviTextureWrapRepeat;
   drawMaterial.WrapModeT = gviTextureWrapMode.gviTextureWrapRepeat;

   primitive.Material = drawMaterial;
   group.AddPrimitive(primitive);
   model.AddGroup(group);
   //通过model创建modelpoint和rendermodelpoint
   var modelName = "1";
   //把模型添加到内存中
   rendercontrol.ObjectManager.AddModel(modelName, model);

   //创建可视化模型
   IModelPoint modelPoint = gFactory.CreateGeometry(gviGeometryType.gviGeometryModelPoint, gviVertexAttribute.gviVertexAttributeZ) as IModelPoint;
   modelPoint.ModelName = modelName;
   modelPoint.ModelEnvelope = model.Envelope;
   modelPoint.SetCoords(100, 100, 100, 0, 0);
   var renderModelPoint = rendercontrol.ObjectManager.CreateRenderModelPoint(modelPoint, null, __rootId);
   rendercontrol.Camera.FlyToObject(renderModelPoint.Guid, gviActionCode.gviActionFlyTo);//设置相机飞到线对象
}

2. JS

2.1 创建模型

function createModelPoint(){
      //设置交互模型、拾取对象、选取模型,注册事件
      __g.interactMode = gviInteractMode.gviInteractSelect;
      //MouseSelectMode与MouseSelectObjectMask之间的调用不存在顺序问题。
      __g.mouseSelectObjectMask = gviMouseSelectObjectMask.gviSelectAll; 
      __g.mouseSelectMode = gviMouseSelectMode.gviMouseSelectClick;
      __g.onmouseclickselect = fnonmouseclickselect;
}

2.2 单击事件 返回值 (相交得到的对象、相交点、判断是否多键按下枚举值、事件发出者)

function fnonmouseclickselect(pickResult, intersectPoint, mask, eventSender){
      if (intersectPoint == null)
              return;
      if (eventSender == gviMouseSelectMode.gviMouseSelectClick) {
	     //1、根据本地文件,获取model和image,创建模型
	     var modelPath="D:\\citymakerbookdata\\Car\\TCJ006.osg";
	     var modelPoint=__g.geometryFactory.createGeometry(gviGeometryType.gviGeometryModelPoint, gviVertexAttribute.gviVertexAttributeZ);
	         modelPoint.modelName=modelPath;
	
	     modelPoint.setCoords(intersectPoint.x,intersectPoint.y,intersectPoint.z,0,0);
	     var rModelPoint=__g.objectManager.createRenderModelPoint(modelPoint,null,__rootId);
	     __g.camera.flyToObject(rModelPoint.guid,gviActionCode.gviActionFlyTo);
		
	     //2、根据数据集中模型库和纹理库中创建模型
	     //先把模型和纹理添加到模型库和纹理库,通过程序或者builder
	     var modelPath="D:\\citymakerbookdata\\Car\\TCJ006.osg";
	     var modelAndImage=__g.resourceFactory.createModelAndImageFromFile(modelPath);
	
	     var images=modelAndImage.images;
	     var model=modelAndImage.model;
	     var matrix=modelAndImage.matrix;
	     var modelName="TCJ006";//如果是存入内存或者fdb中的资源,设置modleName只需要设置名称,而不是路径
	     dateSet.addModel(modelName,model,null);//添加模型到资源库中,fc提前准备好的资源fc
	     var count=images.getCount();
	
	    if(count>0){
	      var imageNames=images.getAllKeys();
	      for(var i = 0; i < count; i++){
	             var imageName = imageNames[i];
	             var img = images.getProperty(imageName);
	             dateSet.addImage(imageName, img);
	             __g.refreshImage(dateSet, imageName);
	       }
	    }
	    __g.refreshModel(dateSet,modelName);
	
	
	    //创建模型
	    var modelPoint=__g.geometryFactory.createGeometry(gviGeometryType.gviGeometryModelPoint, gviVertexAttribute.gviVertexAttributeZ);
	
	    //设置创建可视化模型所有资源的位置,可以默认内存,或者设置从数据集中获取
	    var modelPointSymbol = __g.new_ModelPointSymbol;
	    modelPointSymbol.setResourceDataSet(dateSet);
	    modelPoint.setCoords(intersectPoint.x,intersectPoint.y,intersectPoint.z,0,0);
	    modelPoint.modelName = "TCJ006";
	    modelPoint.modelEnvelope = model.envelope;
	    var rModelPoint = __g.objectManager.createRenderModelPoint(modelPoint, modelPointSymbol, __rootId);
	    __g.camera.flyToObject(rModelPoint.guid,gviActionCode.gviActionFlyTo);
	
	    //3、通过顶点数组和纹理数组构建模型,纹理通过本地或者纹理库  
	    createModel(intersectPoint);
    }
}

2.3 创建模型 贴纹理

function createModel(intersectPoint) {
       //创建一个空模型
       var model = __g.resourceFactory.createModel();
       //通过本地文件创建图片
       var image = __g.resourceFactory.createImageFromFile("D:\\citymakerbookdata\\point.png");
       var imagesName = "1";
       //把贴图添加到内存中
       __g.objectManager.addImage(imagesName, image);

       //创建绘制组和绘制单元
       var group = __g.new_DrawGroup;
       var primitive = __g.new_DrawPrimitive;
       //顶点数组   不用索引数组的情况下  顶点坐标 xyz格式 逆时针
       var vertexArray = __g.new_FloatArray;
       vertexArray.array=[0,0,0,10,0,0,0,10,0,10,0,0,10,10,0,0,10,0,0,0,0,10,0,10,0,0,10,0,0,0,10,0,0,10,0,10,10,0,0,10,10,0,10,10,10,10,0,0,10,10,10,10,0,10,10,10,0,0,10,0,0,10,10,10,10,0,0,10,10,10,10,10,0,10,0,0,0,0,0,0,10,0,10,0,0,0,10,0,10,10,0,0,10,10,0,10,10,10,10,0,0,10,10,10,10,0,10,10];
       primitive.vertexArray = vertexArray;
       //纹理坐标 uv格式  纹理坐标跟顶点坐标是一一对应
       var texcoordArray = __g.new_FloatArray;
       texcoordArray.array =[0,0,1,0,0,1,1,0,1,1,0,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1];
       primitive.texcoordArray = texcoordArray;

       //设置材质
       var drawMaterial = __g.new_DrawMaterial;
       drawMaterial.diffuseColor = 0xFF1093ED; //漫反射颜色
       drawMaterial.enableLight = true; //开启光照
       drawMaterial.cullMode = gviCullFaceMode.gviCullNone; //双面显示
       drawMaterial.textureName = imagesName;
       drawMaterial.wrapModeS = gviTextureWrapMode.gviTextureWrapRepeat;
       drawMaterial.wrapModeT = gviTextureWrapMode.gviTextureWrapRepeat;
       primitive.material = drawMaterial;
       group.addPrimitive(primitive);
       model.addGroup(group);

       //通过model创建modelpoint和rendermodelpoint
       var modelName = "1";
       //把模型添加到内存中
       __g.objectManager.addModel(modelName, model);
       var modelPoint = __g.geometryFactory.createGeometry(gviGeometryType.gviGeometryModelPoint, gviVertexAttribute.gviVertexAttributeZ);
       modelPoint.modelName = modelName;
       modelPoint.modelEnvelope = model.envelope;
       modelPoint.setCoords(intersectPoint.x,intersectPoint.y,intersectPoint.z,0,0);
       //创建可视化模型
       var renderModelPoint = __g.objectManager.createRenderModelPoint(modelPoint, null, __rootId);
       __g.camera.flyToObject(renderModelPoint.guid,gviActionCode.gviActionFlyTo);//设置相机飞到线对象
}

三:注意事项

1、通过文件创建模型和纹理,modelName为本地路径,通过内存或者资源库创建,modleName为osg名称即可。
2、绘制模型的时候,顶点数组和纹理数组要一一对应,顶点数组为[x,y,z]格式,纹理数组为[u,v]格式,并且加点顺序为逆时针方向。
3、加载到内存中创建可视化模型时不需要设置symbol,如果是用资源库中的资源,需要设置modelPointsymbol,获取资源的dataset。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值