iOS开发之SceneKit框架--SCNGeometry.h

1、SCNGeometry简介

  SCNGeometry负责呈现三维模型的类,它管理者物体的形状、纹理等。它可以由SCNGeometrySource和SCNGeometryElement来构造, 一个SCNGeometry 可以包含多个SCNGeometrySource和SCNGeometryElement对象. 还可以通过SCNMaterial定义几何形状表面的颜色或者纹理, SCNLight 定义光照效果, SCNProgram 设计OpenGL或者Metal着色语言等等。

  SCNGeometrySource 在SceneKit中就是顶点的集合. 这些点用来构成一个几何图形. 创建了一个SCNGeometrySource对象,包含有2个顶点, 可以用来绘制一条直线.

  SCNGeometryElement 用来描述如何把SCNGeometrySource中的顶点构成基本的几何图形. SCNGeometryPrimitiveType定义了在SceneKit所支持的基本几何图形的种类,

2、相关API简介

  • 初始化
//懒加载,ios初始化用init
+ (instancetype)geometry API_AVAILABLE(macos(10.9));
//通过SCNGeometrySource和SCNGeometryElement对象创建
+ (instancetype)geometryWithSources:(NSArray<SCNGeometrySource *> *)sources elements:(nullable NSArray<SCNGeometryElement *> *)elements;
  • 几何属性管理
//名字
@property(nonatomic, copy, nullable) NSString *name;
  • 几何材料的管理
//确定几何图形的外观(也就是说用什么样的材料)
@property(nonatomic, copy) NSArray<SCNMaterial *> *materials;

//确定几何体的第一个材料,如果没有返回nil
@property(nonatomic, retain, nullable) SCNMaterial *firstMaterial;

//新建材料material在材料数组中插入指定位置index
- (void)insertMaterial:(SCNMaterial *)material atIndex:(NSUInteger)index;

//从材料数组中移除指定位置的材料
- (void)removeMaterialAtIndex:(NSUInteger)index;

//新建材料material在材料数组中替换指定位置index的材料
- (void)replaceMaterialAtIndex:(NSUInteger)index withMaterial:(SCNMaterial *)material;

//返回与指定名称连接的第一个材料。
- (nullable SCNMaterial *)materialWithName:(NSString *)name;
  • 几何数据的管理
//为几何图形提供顶点数据
@property(nonatomic, readonly) NSArray<SCNGeometrySource *> *geometrySources API_AVAILABLE(macos(10.10));

//返回指定语句的顶点数据
- (NSArray<SCNGeometrySource *> *)geometrySourcesForSemantic:(SCNGeometrySourceSemantic)semantic;

//描述几何形状的几何元素数组
@property(nonatomic, readonly) NSArray<SCNGeometryElement *> *geometryElements API_AVAILABLE(macos(10.10));

//几何图形元素的个数
@property(nonatomic, readonly) NSInteger geometryElementCount;

//返回指定索引处的几何元素
- (SCNGeometryElement *)geometryElementAtIndex:(NSInteger)elementIndex;
  • 优化的详细级别
//管理几何的外观当视图很远时。一种可以自动替换的几何图形的替代解决方案,以提高渲染性能。
//一个SCNLevelOfDetail数组,SCNLevelOfDetail代表模型的细节层次,比如获取SCNGeometry属性等。
@property(nonatomic, copy, nullable) NSArray<SCNLevelOfDetail *> *levelsOfDetail API_AVAILABLE(macos(10.9));
  • 平滑和细分几何
//指定接收器的细分级别。默认值为0。
//分等级0表示没有细分。当接收器的“tessel”属性不是nil时,对GPU进行细化。
@property(nonatomic) NSUInteger subdivisionLevel API_AVAILABLE(macos(10.10));

//自适应细分,默认值是YES,要求接收方的“tessel”属性不是nil。
@property(nonatomic) BOOL wantsAdaptiveSubdivision API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));

//指定控制子分区的边缘折痕
//在细分后,几何元素识别几何图形的边缘应该保持锋利。这种几何元素的原始类型必须是SCNGeometryPrimitiveTypeLine。
//请参见上面的subdivisionLevel来控制子分区的级别
@property(nonatomic, retain, nullable) SCNGeometryElement *edgeCreasesElement API_AVAILABLE(macos(10.10));

//指定表面细分后边缘的平滑度或锐度。
//这个几何源的语义必须是“SCNGeometrySourceSemanticEdgeCrease”。折痕值是介于0和10之间的浮动值,其中0表示平滑,10表示无限锐。
//请参见上面的subdivisionLevel来控制子分区的级别。请参阅上面的edgecreeselement来指定边缘折痕的边缘。
@property(nonatomic, retain, nullable) SCNGeometrySource *edgeCreasesSource API_AVAILABLE(macos(10.10));
  • 管理镶嵌
//指定如何在GPU的呈现时间内对几何图形进行镶嵌。默认为零
#if SCN_ENABLE_METAL
@property(nonatomic, retain, nullable) SCNGeometryTessellator *tessellator API_AVAILABLE(macos(10.13), ios(11.0)) API_UNAVAILABLE(tvos, watchos);
#endif

3、SCNGeometrySource顶点集合相关API简介

  • 官方示例
typedef struct {
    float x, y, z;    // position
    float nx, ny, nz; // normal
    float s, t;       // texture coordinates
} MyVertex;

MyVertex vertices[VERTEX_COUNT] = { /* ... vertex data ... */ };
NSData *data = [NSData dataWithBytes:vertices length:sizeof(vertices)];
SCNGeometrySource *vertexSource, *normalSource, *tcoordSource;

vertexSource = [SCNGeometrySource geometrySourceWithData:data
                                                semantic:SCNGeometrySourceSemanticVertex
                                             vectorCount:VERTEX_COUNT
                                         floatComponents:YES
                                     componentsPerVector:3 // x, y, z
                                       bytesPerComponent:sizeof(float)
                                              dataOffset:offsetof(MyVertex, x)
                                              dataStride:sizeof(MyVertex)];

normalSource = [SCNGeometrySource geometrySourceWithData:data
                                                semantic:SCNGeometrySourceSemanticNormal
                                             vectorCount:VERTEX_COUNT
                                         floatComponents:YES
                                     componentsPerVector:3 // nx, ny, nz
                                       bytesPerComponent:sizeof(float)
                                              dataOffset:offsetof(MyVertex, nx)
                                              dataStride:sizeof(MyVertex)];

tcoordSource = [SCNGeometrySource geometrySourceWithData:data
                                                semantic:SCNGeometrySourceSemanticTexcoord
                                             vectorCount:VERTEX_COUNT
                                         floatComponents:YES
                                     componentsPerVector:2 // s, t
                                       bytesPerComponent:sizeof(float)
                                              dataOffset:offsetof(MyVertex, s)
                                              dataStride:sizeof(MyVertex)];
  • 创建几何源
/**
 从给定的数据和参数中创建并返回一个几何源。

 @param data 几何数据。
 @param semantic 枚举值SCNGeometrySourceSemantic
 @param vectorCount 几何源向量的个数。
 @param floatComponents 指示向量组件是否为浮点值的标志。
 @param componentsPerVector 向量中标量分量的数目。
 @param bytesPerComponent 表示向量组件的字节数。
 @param offset 从数据开始的偏移量
 @param stride 数据中从一个向量到另一个向量的字节数。
 @return SCNGeometrySource
 */
+ (instancetype)geometrySourceWithData:(NSData *)data semantic:(SCNGeometrySourceSemantic)semantic vectorCount:(NSInteger)vectorCount floatComponents:(BOOL)floatComponents componentsPerVector:(NSInteger)componentsPerVector bytesPerComponent:(NSInteger)bytesPerComponent dataOffset:(NSInteger)offset dataStride:(NSInteger)stride;

/**
 从顶点位置的数组中创建一个几何源。

 @param vertices 顶点
 @param count 顶点数量
 @return SCNGeometrySource
 */
+ (instancetype)geometrySourceWithVertices:(const SCNVector3 *)vertices count:(NSInteger)count;

/**
 从法向量的数组中创建一个几何源

 @param normals 法线的缓冲区。
 @param count 法线的数量。
 @return SCNGeometrySource
 */
+ (instancetype)geometrySourceWithNormals:(const SCNVector3 *)normals count:(NSInteger)count;

/**
 从纹理坐标点的数组中创建一个几何源。

 @param texcoord 纹理坐标的缓冲区。
 @param count 纹理坐标点的数量。
 @return SCNGeometrySource
 */
+ (instancetype)geometrySourceWithTextureCoordinates:(const CGPoint *)texcoord count:(NSInteger)count;
  • 检查几何来源
//几何图形的数据来源
@property(nonatomic, readonly) NSData *data;

//每个顶点的语义值 枚举
@property(nonatomic, readonly) SCNGeometrySourceSemantic semantic;

//向量的个数
@property(nonatomic, readonly) NSInteger vectorCount;

//该值指示向量组件是否为浮点值。
@property(nonatomic, readonly) BOOL floatComponents;

//标量的组件的数量
@property(nonatomic, readonly) NSInteger componentsPerVector;

//每个向量组件的大小
@property(nonatomic, readonly) NSInteger bytesPerComponent;

//以字节为单位的偏移量,从数据的开始到第一个在几何源中使用的向量组件。
@property(nonatomic, readonly) NSInteger dataOffset;

//数据中从一个向量到另一个向量的字节数。
@property(nonatomic, readonly) NSInteger dataStride;
  • 创建GPU-Mutable几何来源
/**
 创建一个几何源,其顶点数据位于指定的金属缓冲区中,允许通过金属计算着色器进行修改。

 @param mtlBuffer 一个金属缓冲器。
 @param vertexFormat 顶点格式
 @param semantic 枚举SCNGeometrySourceSemantic
 @param vertexCount 顶点的数目。
 @param offset 数据开始时的偏移量
 @param stride 从一个向量到数据中的下一个向量的字节数。
 @return SCNGeometrySource

 试图修改SCNSceneRenderer委托调用之外的金属缓冲区的讨论是没有定义的。
 通常使用它在willRenderScene回调中修改MTLBuffer,在用户自己的命令缓冲区中使用计算内核或顶点函数。所以类似:
 - (void)renderer:(id <SCNSceneRenderer>)aRenderer willRenderScene:(SCNScene *)scene atTime:(NSTimeInterval)time
 {
 // 请求新的命令缓冲区。
 id <MTLCommandBuffer> myCommandBuffer = [aRenderer.commandQueue commandBuffer];

 // 获取一个计算命令编码器。
 id <MTLComputeCommandEncoder> myComputeCommandEncoder = [myCommandBuffer computeCommandEncoder];

 // 配置计算命令编码器的管道状态、缓冲区输入等…
 //...
 // 调度
 [myComputeCommandEncoder dispatchThreadgroups:numberOfWorkingGroups threadsPerThreadgroup:numberOfThreads];
 [myComputeCommandEncoder endEncoding];
 [myCommandBuffer commit];
 }
 */
+ (instancetype)geometrySourceWithBuffer:(id <MTLBuffer>)mtlBuffer vertexFormat:(MTLVertexFormat)vertexFormat semantic:(SCNGeometrySourceSemantic)semantic vertexCount:(NSInteger)vertexCount dataOffset:(NSInteger)offset dataStride:(NSInteger)stride API_AVAILABLE(macos(10.11), ios(9.0));
  • SCNGeometrySourceSemantic枚举值
#if defined(SWIFT_SDK_OVERLAY2_SCENEKIT_EPOCH) && SWIFT_SDK_OVERLAY2_SCENEKIT_EPOCH >= 3
typedef NSString * SCNGeometrySourceSemantic NS_EXTENSIBLE_STRING_ENUM;
#else
typedef NSString * SCNGeometrySourceSemantic;
#endif

FOUNDATION_EXTERN SCNGeometrySourceSemantic const SCNGeometrySourceSemanticVertex;//顶点位置数据的语义
FOUNDATION_EXTERN SCNGeometrySourceSemantic const SCNGeometrySourceSemanticNormal;//表面正常数据的语义
FOUNDATION_EXTERN SCNGeometrySourceSemantic const SCNGeometrySourceSemanticColor;//每个顶点颜色数据的语义。
FOUNDATION_EXTERN SCNGeometrySourceSemantic const SCNGeometrySourceSemanticTexcoord;//纹理坐标数据的语义。
FOUNDATION_EXTERN SCNGeometrySourceSemantic const SCNGeometrySourceSemanticTangent API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0));//表面切矢量数据的语义
FOUNDATION_EXTERN SCNGeometrySourceSemantic const SCNGeometrySourceSemanticVertexCrease API_AVAILABLE(macos(10.10));//用于细分曲面的顶点折痕数据的语义
FOUNDATION_EXTERN SCNGeometrySourceSemantic const SCNGeometrySourceSemanticEdgeCrease API_AVAILABLE(macos(10.10));//用于细分曲面的边缘折痕数据的语义
FOUNDATION_EXTERN SCNGeometrySourceSemantic const SCNGeometrySourceSemanticBoneWeights API_AVAILABLE(macos(10.10));//骨重量数据的语义,用于皮肤表面的骨骼动画
FOUNDATION_EXTERN SCNGeometrySourceSemantic const SCNGeometrySourceSemanticBoneIndices API_AVAILABLE(macos(10.10));//骨指数数据的语义,用于皮肤表面的骨骼动画。

4、SCNGeometryElement几何元素相关API简介

  • 初始化
/**
 从指定的数据和选项创建一个几何元素

 @param data 包含元素索引的数据。您可以通过nil来使用隐式顶点排序(0,1,2…)。
 @param primitiveType SCNGeometryPrimitiveType枚举值
 @param primitiveCount 数据中的基元数。
 @param bytesPerIndex 表示数据中单个索引值的字节数。
 @return SCNGeometryElement
 */
+ (instancetype)geometryElementWithData:(nullable NSData *)data primitiveType:(SCNGeometryPrimitiveType)primitiveType primitiveCount:(NSInteger)primitiveCount bytesPerIndex:(NSInteger)bytesPerIndex;
  • 使用索引
//描述几何元素的数据。
@property(nonatomic, readonly) NSData *data;

//SCNGeometryPrimitiveType 枚举值
@property(nonatomic, readonly) SCNGeometryPrimitiveType primitiveType;

//元素中的基元数。
@property(nonatomic, readonly) NSInteger primitiveCount;

//范围渲染。默认为[NSNotFound,0]
//当将范围的位置设置为NSNotFound时,将呈现整个几何元素。
@property(nonatomic) NSRange primitiveRange API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));

//表示元素数据中的每个索引值的字节数。
@property(nonatomic, readonly) NSInteger bytesPerIndex;
  • SCNGeometryPrimitiveType枚举值
typedef NS_ENUM(NSInteger, SCNGeometryPrimitiveType) {
    SCNGeometryPrimitiveTypeTriangles                                                  = 0,//几何元素的数据是一个三角形序列,每个三角形由三个新的顶点描述。
    SCNGeometryPrimitiveTypeTriangleStrip                                              = 1,//几何元素的数据是一个三角形序列,每个三角形由一个新顶点和前一个三角形的两个顶点描述。
    SCNGeometryPrimitiveTypeLine                                                       = 2,//几何元素的数据是一个线段序列,每个线段由两个新的顶点描述。
    SCNGeometryPrimitiveTypePoint                                                      = 3,//几何元素的数据是一个未连接点的序列。
#if defined(SWIFT_SDK_OVERLAY2_SCENEKIT_EPOCH) && SWIFT_SDK_OVERLAY2_SCENEKIT_EPOCH >= 2
    SCNGeometryPrimitiveTypePolygon API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0)) = 4//多边形
#endif
};
#if !(defined(SWIFT_SDK_OVERLAY2_SCENEKIT_EPOCH) && SWIFT_SDK_OVERLAY2_SCENEKIT_EPOCH >= 2)
#define SCNGeometryPrimitiveTypePolygon (SCNGeometryPrimitiveType)4
#endif
  • 呈现点云
//使用这些属性将一个几何图形显示为一个点集合,而不是一个固体表面或线框。

//几何元素中各点的宽度,如几何图形中的局部三维坐标空间。默认1
@property(nonatomic) CGFloat pointSize API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));

//在屏幕点上测量的最小的半径,用来渲染几何元素中的任何一点。默认1
@property(nonatomic) CGFloat minimumPointScreenSpaceRadius API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));

//最大的半径,测量在屏幕上的点,在其中渲染任何一点的几何元素。默认1
@property(nonatomic) CGFloat maximumPointScreenSpaceRadius API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));

5、SCNGeometryTessellator几何镶嵌者相关API简介

  • 实例属性
//指定用于每个贴片镶嵌因素的比例因子。默认为1。
@property(nonatomic) CGFloat tessellationFactorScale;

//指定镶嵌划分模式。默认为MTLTessellationPartitionModeInteger。
@property(nonatomic) MTLTessellationPartitionMode tessellationPartitionMode;
typedef NS_ENUM(NSUInteger, MTLTessellationPartitionMode) {
    MTLTessellationPartitionModePow2 = 0,
    MTLTessellationPartitionModeInteger = 1,
    MTLTessellationPartitionModeFractionalOdd = 2,
    MTLTessellationPartitionModeFractionalEven = 3,
} NS_ENUM_AVAILABLE(10_12, 10_0);

//指定镶嵌应该是统一的还是自适应的。默认为NO
@property(nonatomic, getter=isAdaptive) BOOL adaptive;

//指定在屏幕空间中是否应该调整镶嵌的水平。默认为NO
@property(nonatomic, getter=isScreenSpace) BOOL screenSpace;

//指定边缘镶嵌因子。默认为1。
@property(nonatomic) CGFloat edgeTessellationFactor;

//指定内部镶嵌因素。默认为1
@property(nonatomic) CGFloat insideTessellationFactor;

//指定最大边长。默认为1。
@property(nonatomic) CGFloat maximumEdgeLength;
  • 选择一个平滑算法SCNTessellationSmoothingMode枚举
//默认是SCNTessellationSmoothingModeNone
@property(nonatomic) SCNTessellationSmoothingMode smoothingMode;
typedef NS_ENUM(NSInteger, SCNTessellationSmoothingMode) {
    SCNTessellationSmoothingModeNone = 0,
    SCNTessellationSmoothingModePNTriangles,//PN-Triangles是控制曲面的算法法,P表现point,N表示法线,Triangles说明总有有3个点其对应的法线,这个算法很适用于实时渲染中的曲面生成,空间的最基本的面就是三角形面。
    SCNTessellationSmoothingModePhong// phong 光照模型渲染效果。
} API_AVAILABLE(macos(10.13), ios(11.0)) API_UNAVAILABLE(tvos, watchos);

原文地址:https://www.cnblogs.com/xianfeng-zhang/p/8984809.html

时间: 2024-10-19 12:23:29

iOS开发之SceneKit框架--SCNGeometry.h的相关文章

iOS开发之SceneKit框架--SCNLight.h

1.SCNLight简介 用于添加光源,连接到一个节点照亮现场,可以给场景添加不同的灯光,模拟逼真的环境. 2.四种灯光的简介 添加一个box立方体.一个tube圆柱管道和一个地板floor,没有灯光的时候物体都是白色的模型图: 四种灯光分别为环境光.全方位光.定向光和点光源,另外还有一个光域网和荧光探针.添加不同灯光后效果如下: //灯光类型 枚举 @property(nonatomic, copy) SCNLightType type; FOUNDATION_EXTERN SCNLightT

iOS开发之CoreLocaiton框架使用(定位服务)

前言 在iOS开发中,定位和地图功能是比较常用的功能之一,要想加入这2大功能,必须基于2个框架进行开发. (1) CoreLocation:用于地理定位,地理编码,区域监听等(着重功能实现). (2) MapKit:用于地图展示,例如大头针,路线.覆盖层展示等(着重界面展示). 这篇文章我们来着重的介绍下CoreLocation框架 简介 CoreLocaiton框架是百度地图的定位也是在苹果API的基础上进行了封装. CoreLocation框架使用前提 导入框架(Xcode5.0之后可以省略

iOS开发之Masonry框架源码深度解析

Masonry是iOS在控件布局中经常使用的一个轻量级框架,Masonry让NSLayoutConstraint使用起来更为简洁.Masonry简化了NSLayoutConstraint的使用方式,让我们可以以链式的方式为我们的控件指定约束.本篇博客的主题不是教你如何去使用Masonry框架的,而是对Masonry框架的源码进行解析,让你明白Masonry是如何对NSLayoutConstraint进行封装的,以及Masonry框架中的各个部分所扮演的角色是什么样的.在Masonry框架中,仔细

iOS开发之Masonry框架源码解析

Masonry是iOS在控件布局中经常使用的一个轻量级框架,Masonry让NSLayoutConstraint使用起来更为简洁.Masonry简化了NSLayoutConstraint的使用方式,让我们可以以链式的方式为我们的控件指定约束.本篇博客的主题不是教你如何去使用Masonry框架的,而是对Masonry框架的源码进行解析,让你明白Masonry是如何对NSLayoutConstraint进行封装的,以及Masonry框架中的各个部分所扮演的角色是什么样的.在Masonry框架中,仔细

李洪强iOS开发之Foundation框架—集合

Foundation框架—集合 一.NSArray和NSMutableArray (一)NSArray不可变数组 (1)NSArray的基本介绍 NSArray是OC中使用的数组,是面向对象的,以面向对象的形式操纵对象,是不可变数组. C语言数组有一个缺点即数组中只能存放同种数据类型的元素. OC数组只能存放OC对象,不能存放非OC对象,如int,结构体和枚举等. (2)NSArray的创建 (3)NSArray的访问 (4)NSArray的遍历 数组的遍历有以下几种方式: 首先创建一个数组 第

iOS开发之MVVM在项目中的应用

今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦~). 由于本人项目经验有限,关于架构设计方面的东西理解有限,我个人对MVVM的理解主要是借鉴于之前的用过的MVC的Web框架~在学校的时候用过ThinkPHP框架,和SSH框架,都是MVC的架构模式,今天MVVM与传统的MVC可谓是极为相似,也可以说是兄弟关系,也就是一家人了. 说到架构设计和团队

李洪强IOS开发之-iOS经典面试题

李洪强IOS开发之-iOS经典面试题 写这篇文章的目的是因为前两天同学想应聘iOS开发,从网上找了iOS面试题和答案让我帮忙看看.我扫了一眼,倒吸了一口冷气,仔细一看,气的发抖.整篇题目30多个没有一个答案是对的,总结这篇面试题的作者对iOS机制根本就是一知半解就敢发到网上,不管有心还是无心都是坑害新人.所以在这里总结一下这几年面试别人和被别人面试遇到的一些我认为比较好的基础题目分享给大家,进阶题目在后续补充.我的理解如果有错漏请一定指出,非常感谢! 从12年开始做面试官到现在已经三个年头了,这

iOS开发之Auto Layout入门

随着iPhone6与iOS8的临近,适配的问题讲更加复杂,最近学习了一下Auto Layout的使用,与大家分享.  什么是Auto Layout? Auto Layout是iOS6发布后引入的一个全新的布局特性,其目的是弥补以往Autoresizing在布局方面的不足之处,以及未来面对更多尺寸适配时界面布局可以更好的适应. 为什么要用Auto Layout? Autolayout能解决不同屏幕(iPhone4,iPhone5,iPad...)之间的适配问题. 在iPhone4时代开发者只需要适

iOS开发之UISearchBar初探

iOS开发之UISearchBar初探 UISearchBar也是iOS开发常用控件之一,点进去看看里面的属性barStyle.text.placeholder等等.但是这些属性显然不足矣满足我们的开发需求.比如:修改placeholder的颜色.修改UISearchBar上面的UITextfield的背景颜色.修改UITextfield上面的照片等等. 为了实现上述的需求,最好写一个UISearchBar的子类就叫LSSearchBar吧 LSSearchBar.h如下: #import <U