Code Monkey home page Code Monkey logo

s3m-spec's Introduction

Version 1.0

Spatial 3D Model (S3M)是一种适用于海量三维模型数据的传输格式。它通过一种高效,易扩展,可协作的数据规范,在不同终端(移动,浏览器,桌面)之间,满足用户在三维数据传输和解析方面的各类需求。

效果

简介

随着倾斜技术的日趋成熟,超图三维研发团队形成了一套C/S下成熟的倾斜数据的解决方案,接下来,如何在Web端应用倾斜数据成为一个迫切的需求。OSGB格式,被认为是倾斜摄影模型的文件格式标准,其数据规范很好的解决了海量三维模型数据的高效浏览,但数据结构过于复杂,性能消耗和解析时间都无法满足Web的用户体验。为了改进海量异构数据集的传输和渲染性能, Cesium推出了开发标准3D-Tiles,一种空间数据结构、一套为三维而生的切片格式。

超图三维研发团队在OSGB和3D-Tiles的基础上各取所长,并对倾斜数据,精模,BIM,矢量,管线,单体化,实例化等相关内容的整合,最终形成了海量三维数据规范---S3M,很好的解决了大规模三维数据在B/S下传输和解析这两大瓶颈,并提供S3M、OSGB、3D-Tiles之间的转换功能。除了倾斜摄影模型,BIM,精细模型和管线等数据,S3M同时还支持其他各类数据,比如点云、水面以及三维场等多种数据。

当然,超图三维产品不仅仅提出S3M数据规范,而是基于该数据规范形成了一套B/S下完整的解决方案,从数据生成,服务端发布,到多种客户端加载应用等多个环节解决用户的实际问题。 S3M的形成基于OSGB和3D-Tiles并结合超图三维多年来在技术,产品,应用的积累。总体来说,主要有以下几个特点:

  • 高效,支持大数据量,更好的利用图形硬件加速

    • 支持LOD
    • 支持实例化绘制
    • 支持批次绘制
  • 支持对象高效选择

  • 和3D-Tiles类似,适合作为底图,高效的绘制,不适合编辑

  • S3M格式简洁,更适合在WebGL等轻量级端使用

概念

空间坐标系

S3M采用右手坐标系,所有线性距离单位为米,空间坐标系仅支持WGS84坐标系。如果原始数据为非WGS84坐标系,可以通过Supermap iDesktop产品,在生成S3M数据时进行投影转换。

平面坐标系

现在S3M也支持在平面场景中加载,其坐标系是基于数据的本地坐标系,这也实现了真正意义上的二三维一体化。

树结构

在空间数据结构上,S3M数据和倾斜数据的切片规范一样,通过树状结构来管理和维护。树中有一个根节点和它对应的子节点,同一级的节点之间数据量尽可能相同,在空间关系是上,父节点包含其所有子节点,并通过树的层级关系来组织和管理。

如下图,在浏览时,根据相机距离的远近,选择适合的节点切片,达到效果和效率之间的平衡。

SCP文件

<?xml version="1.0" encoding="UTF-8"?>
<SuperMapCache xmlns:sml="http://www.supermap.com/SuperMapCache/vectorltile">
<sml:Version>1.00000</sml:Version>
<sml:FileType>OSGBFile</sml:FileType>
<sml:HeightRange>
	<sml:MaxHeight>48.945885</sml:MaxHeight>
	<sml:MinHeight>6.386441</sml:MinHeight>
</sml:HeightRange>
<sml:Position>
	<sml:X>115.000000000000000</sml:X>
	<sml:Y>40.000000000000000</sml:Y>
	<sml:Z>0.000000000000000</sml:Z>
</sml:Position>
<sml:BoundingBox>
	<sml:MinX>-1081.6277399394771</sml:MinX>
	<sml:MinY>-581.01017007240466</sml:MinY>
	<sml:MinZ>-335.26080412402422</sml:MinZ>
	<sml:MaxX>-364.71959173626021</sml:MaxX>
	<sml:MaxY>135.89797813081219</sml:MaxY>
	<sml:MaxZ>381.64734407919258</sml:MaxZ>
</sml:BoundingBox>
<sml:OSGFiles>
	<sml:Files>
	<sml:FileName>./Tile_007_009/Tile_007_009.s3m</sml:FileName>
	<sml:BoundingSphere>
		<sml:CenterX>-738.053833</sml:CenterX>
		<sml:CenterY>-521.840881</sml:CenterY>
		<sml:CenterZ>24.340384</sml:CenterZ>
		<sml:Radius>36.200244</sml:Radius>
	</sml:BoundingSphere>
	</sml:Files>
</sml:OSGFiles>
</SuperMapCache>

SCP是S3M数据的配置信息,以XML形式提供,主要属性如下:

  • FileType:数据类型,倾斜,BIM,精模等
  • Position:数据的位置,经度+纬度+高度
  • BoundingBox:数据空间范围
  • OSGFiles/FileName:根节点集合
  • BoundingSphere:根节点空间范围

切片

在树状结构中,每一个节点对应一个切片(Tile,后缀为s3m)。每个切片都包括四个部分:

  • 表述信息,XML格式,文本形式
  • 几何对象集合,二进制形式
  • 单体化信息,二进制形式
  • 纹理信息,二进制形式

XML

<Group>
	<PageLods>
		<PagedLOD>
			<Geode>
				<GeoName>30519188</GeoName>
				<GeoName>3272469703</GeoName>
				<GeoDeModMatrix />
			</Geode>
			<RangeDataList>Tile_+020_+025_L19_000020.osgb</RangeDataList>
			<RangeMode>PIXEL_SIZE_ON_SCREEN</RangeMode>
			<BoundingSphere><x>-1162.754395</x><y>-800.559265</y><z>66.624786</z><radius>48.324287</radius></BoundingSphere>
			<RangeList>386.594299</RangeList>
		</PagedLOD>
		<PagedLOD />
	</PageLods>
	<Material3Ds>
		<material>
			<name>2315486585</name>
			<Ambient><Ambient:R>1.000000</Ambient:R><Ambient:G>1.000000</Ambient:G><Ambient:B>1.000000</Ambient:B><Ambient:A>1.000000</Ambient:A></Ambient>
			<Diffuse><Diffuse:R>1.000000</Diffuse:R><Diffuse:G>1.000000</Diffuse:G><Diffuse:B>1.000000</Diffuse:B><Diffuse:A>1.000000</Diffuse:A></Diffuse>
			<Specular><Specular:R>0.000000</Specular:R><Specular:G>0.000000</Specular:G><Specular:B>0.000000</Specular:B><Specular:A>1.000000</Specular:A></Specular>
			<Shininess>0.000000</Shininess>
			<texture>
				<name>384769527</name>
				<AddressMode>
					<u>TAM_CLAMP</u>
					<v>TAM_CLAMP</v>
					<w>TAM_CLAMP</w>
				</AddressMode>
				<TextureFilteringOption>FO_NONE</TextureFilteringOption>
				<MinFilter>FO_LINEAR</MinFilter>
				<MaxFilter>FO_LINEAR</MaxFilter>
				<MipFilter>FO_POINT</MipFilter>
				<TexModMatrix>1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000</TexModMatrix>
			</texture>
		</material>
	</Material3Ds>
</Group>

如上是每一个S3M中的表述信息,以XML文本形式保存,里面是PageLods和Material3Ds两个集合。

PagedLOD是当前节点和子节点之间的层级关系。首先是子节点的LOD信息(下面会介绍),Geode是当前节点的几何对象信息,如下图,包括GeoName对象名,对应几何对象集合中的唯一标识,GeoDeModMatrix,该对象相对基准点的矩阵。

<Geode>
	<GeoName>30519188</GeoName>
	<GeoName>3272469703</GeoName>
	<GeoDeModMatrix>1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000</GeoDeModMatrix>
</Geode>

Material3Ds中包含该节点用到的所有材质属性。每一个材质对应的属性如下:

<Material3Ds>
		<material>
			<name>2315486585</name>
			<Ambient><Ambient:R>1.000000</Ambient:R><Ambient:G>1.000000</Ambient:G><Ambient:B>1.000000</Ambient:B><Ambient:A>1.000000</Ambient:A></Ambient>
			<Diffuse><Diffuse:R>1.000000</Diffuse:R><Diffuse:G>1.000000</Diffuse:G><Diffuse:B>1.000000</Diffuse:B><Diffuse:A>1.000000</Diffuse:A></Diffuse>
			<Specular><Specular:R>0.000000</Specular:R><Specular:G>0.000000</Specular:G><Specular:B>0.000000</Specular:B><Specular:A>1.000000</Specular:A></Specular>
			<Shininess>0.000000</Shininess>
			<texture>
				<name>384769527</name>
				<AddressMode>
					<u>TAM_CLAMP</u>
					<v>TAM_CLAMP</v>
					<w>TAM_CLAMP</w>
				</AddressMode>
				<TextureFilteringOption>FO_NONE</TextureFilteringOption>
				<MinFilter>FO_LINEAR</MinFilter>
				<MaxFilter>FO_LINEAR</MaxFilter>
				<MipFilter>FO_POINT</MipFilter>
				<TexModMatrix>1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000</TexModMatrix>
			</texture>
		</material>
	</Material3Ds>

Name为材质名,对应材质集合中的唯一标识,如果该材质中有纹理数据,则有texture标签,同时有一个纹理的name,对应纹理集合的唯一标识。

备注:早期,我们把整个树状结构和LOD信息放到一个XML文件中保存,这样做有两个问题,一个是当该数据层级比较复杂时,导致文件很大,难以解析,同时一次性加载解析,性能上也不划算,因此我们将整个树状结构分解到每个节点中,该节点只保存和子节点之间的关系,深度为1.这样解析简单,做到按需解析。

LOD

LOD类似于影像金字塔,或二维地图层级的概念,用来负责父子节点的切换,根据当前相机的位置和节点的精细程度,来判断是否用多个子节点来替换。通常,节点深度越大,则数据越精细,范围越小,这样通过合理的LOD策略,在当前范围内实现效果和数据量之间的平衡。

S3M支持多种LOD策略,如上图的八叉树和四叉树,以及自适应等,同时在对应的端产品中提供对应的图层类来实现(比如WebGL中的S3MTilesLayer),不需要用户关系具体的调度方法。

LOD之间的切换是替换策略,在浏览场景时,从A节点过渡到B节点时,则渲染B节点对应的几何对象,取消甚至卸载A节点内容,并保证较好的过渡效果。

S3M中LOD具体参数如下:

  • RangeDataList
    • 子节点显示精度
  • RangeMode
    • LOD调度方式,目前有DISTANCE_FROM_EYE_POINT和PIXEL_SIZE_ON_SCREEN两种形式
  • BoundingSphere
    • 子节点的空间范围
  • RangeList
    • 子节点对应的S3M文件名,所有子节点都和根节点在同一文件夹下

Geometry

一个切片中可以包含零个或多个几何对象,每个几何对象中包括一个顶点数据,一个或多个顶点索引数据。

几何对象以二进制形式保存和读取,支持点,线,三角网三种类型。详细信息可参考数据结构---Geometry Table部分。

Texture

无论是文件还是显存中,纹理往往是最占空间的部分。因此S3M在纹理处理上,针对B/S使用场景,设备差异等因素,做了大量优化。

首先,S3M中纹理数据保存在文件内,这样避免了单独请求纹理数据的异步传输。其次,针对PC端,Android端,iOS端提供了纹理压缩类型的支持,优化显存占用和内存解析消耗。最后,为了提高纹理的重用,在XML属性中支持设置对应的纹理矩阵。

当然,S3M为了保证纹理效果,支持mipmap技术。纹理数据的详细结构可参考数据结构---Texture Table部分。

单体化信息集合

单体化数据是一张映射表,映射关系为GeoName(1)---ID(1)---nIndex , nOffset,,也就是每一个几何对象,有且仅有一个唯一的ID,并记录该对象对应顶点数据中的起始位置和偏移量。根据该映射关系修改对应的属性值,达到单体化的效果。

实例化

未完待续

数据结构

首先是版本信息,4个字节,前三个为’S, ‘3, ‘M, 第四位是版本号,目前为4(无单体化信息)和5(有单体化信息)两种情况。

XML表述模块

struct strXMLData
{
	// 长度
	int nSize;
	// 内容
	string strXMLContent;
}

Geometry Table模块

struct GeometryTable
{
	// 所有几何对象的字节长度
	int nPackageSize;
	// 几何对象个数
	int nGeoCount;
	// 对应的Geometry内容
	Geometry geoArray[nGeoCount];
}
struct Geometry
{
	// Geometry对应的顶点数据对象
	VertexPackage m_vertexPackage;
	// Geometry顶点索引数目
	int nIndexPackageSize;
	// Geometry对应的顶点索引对象数组
	IndexPackage arrIndexPackage[nIndexPackageSize];
};
struct VertexPackage
{
	// 该对象的ID
	int nGeoName;
	// 数据绘制属性
	int nVertexOptions;
	// 顶点维数
	int nVertexDimension;
	
	// 顶点数目个数
	unsigned int m_nVerticesCount;	
	// 顶点数组偏移
	unsigned short m_nVertexStride;
	// 字节对齐
	unsigned short nAlign;
	// 顶点数组内容
	float m_pVertices[m_nVerticesCount * nVertexDimension];
	
	// 向量数目个数
	unsigned int m_nNormalCount;
	// 向量数组偏移
	unsigned short m_nNormalStride;
	unsigned short nAlign;
	// 向量数目
	float m_pNormals[m_nNormalCount * nVertexDimension];
	
	// 颜色数组个数
	unsigned int m_nVertexColorCount;
	// 颜色数组偏移
	unsigned short m_nVertexColorStride;
	unsigned short nAlign;
	// 颜色数组
	float m_pVertexColor[m_nVertexColorCount];
	
	// 单体化颜色数组个数
	unsigned int m_nSecondVertexColorCount;
	// 单体化颜色数目
	float m_pSecondVertexColor[m_nSecondVertexColorCount];
	
	// 贴图坐标个数
	int nTexCount;
	// 贴图坐标对象
	TextureCoordinate texArray[nTexCount];	
};
struct TextureCoordinate
{
	// 贴图坐标数目
	unsigned int m_TexCoordCount;
	// 贴图坐标维数
	unsigned short m_nTexDimensions;
	// 每组贴图坐标的偏移
	unsigned short m_TexCoordStride;
	// 贴图坐标数据
	float m_pTexCoords[m_TexCoordCount * m_nTexDimensions];
};
struct IndexPackage
{
	// 索引数目
	unsigned int m_nIndexesCount;
	// 是否使用无符整型数据类型
	unsigned char m_enIndexType;
	// 是否使用索引
	bool m_bUseIndex;
	// 数据绘制的方式
	unsigned char m_OperationType;
	unsigned char nAlign;
	// 索引数组,二选一,取决于m_enIndexType
	unsigned short m_pIndexes[m_nIndexesCount];
	unsigned int m_pIndexes[m_nIndexesCount*2];
	
	// 材质数目
	int nPassCount;
	// 材质对应的哈希码
	unsigned int nPassNameHC[nPassCount];
};

SecondColor Table

struct SecondColorTable
{
	// 单体化模块长度 
	int nSecondPackageCount;
	// 单体化个数
	int nSecondColorCount;
	// 单体化数据对象
	SecondColorObj arrSecondColor[nSecondColorCount];
	
};
struct SecondColorObj
{
	// 单体化对象名称
	int nGeoName;
	// 单体化映射表个数
	int nSelectIDsCount;
	// 单体化映射表对象
	SelectColorMap arrSelectColor[nSelectIDsCount];	
};
struct SelectColorMap
{
	// 单体化对象ID
	int nSelectID;
	// 单体化数组长度
	int nSelectCount;
	// 单体化结构体
	SelectInfo arrSelectInfo[nSelectCount];	
};
struct SelectInfo
{
	// 起始点
	int nHigInfoIndex;
	// 个数
	int nHitInfoCount;	
};

Texture Table

struct TextureDataTable
{
	// 纹理数目
	int nTextureCount;
	// 纹理对象
	TextureData arrTextureData[nTextureCount];
};
struct TextureData
{
	// 纹理对应的哈希码
	unsigned int nTextureHashCode;
	// 纹理宽度
	unsigned int m_nWidth;
	// 纹理高度
	unsigned int m_nHeight;
	// 纹理压缩类型:DDS, PVR, ETC
	unsigned int m_nCompressType;
	// 纹理大小
	unsigned int m_nSize;
	// 纹理的像素类型:RGBA
	int m_nFormat;
	// 纹理数据
	unsigned char m_Buffer[m_nSize];
};

工具

数据生成:SuperMap iDesktop

发布服务:SuperMap iServer

客户端:SuperMap iClient3D for WebGL,SuperMap iClient3D for Plugin,SuperMap iMobile for iOS/Android

文件:

S3MTilesParser.js:解析S3M的JS实现

s3m-spec's People

Contributors

liqiujun avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.