zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    Linux之文件处理命令
    Linux基础命令
    rip实验
    Linux基础之磁盘分区
    mysql安装
    centos Apache、php、mysql默认安装路径
    You probably tried to upload too large file. Please refer to documentation for ways to workaround this limit.
    Wrong permissions on configuration file, should not be world writable!
    机器会学习么 学习总结
    实验 5 Spark SQL 编程初级实践
  • 原文地址:https://www.cnblogs.com/xianfeng-zhang/p/8984809.html
Copyright © 2011-2022 走看看