**
三维中创建模型
**
一:技术原理
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。