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

1、SCNParametricGeometry简介

  SCNParametricGeometry用于创建简单的3D模型,比如SCNPlane 平面、SCNPyramid 锥形(金字塔)、SCNBox 立方体、SCNSphere 球体、SCNCylinder 圆柱、SCNCone 圆锥体、SCNTube 圆柱管道、SCNCapsule 胶囊、SCNTorus 圆环面、SCNFloor 地板、SCNText 字体、SCNShape 自定义几何体!

 

2、SCNPlane 平面

  • 效果图

  • 相关代码
- (void)addPlane{
    SCNPlane *plane = [SCNPlane planeWithWidth:10 height:3];
    SCNNode *geoNode = [SCNNode nodeWithGeometry:plane];
    
    plane.firstMaterial.multiply.contents = @"pic5.ipg";
    plane.firstMaterial.diffuse.contents=@"pic5.ipg";
    plane.firstMaterial.multiply.intensity = 0.5;
    plane.firstMaterial.lightingModelName =  SCNLightingModelConstant;
    geoNode.position = SCNVector3Make(0, 6, -20);
    [self.scnScene.rootNode addChildNode:geoNode];
    [geoNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:0 z:2 duration:1]]];
    [self addFloor];
    [self addLight];
}
  • 相关属性(官方图片)

//初始化
+ (instancetype)planeWithWidth:(CGFloat)width height:(CGFloat)height;

//平面宽度
@property(nonatomic) CGFloat width;

//平面高度
@property(nonatomic) CGFloat height;

//沿X轴的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值为1。
@property(nonatomic) NSInteger widthSegmentCount;

//沿Y轴的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值为1。
@property(nonatomic) NSInteger heightSegmentCount;

//平面圆角半径
@property(nonatomic) CGFloat cornerRadius API_AVAILABLE(macos(10.9));

//圆角的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值是10。
@property(nonatomic) NSInteger cornerSegmentCount API_AVAILABLE(macos(10.9));

 

3、SCNBox 立方体

  • 效果图

 

  • 相关代码
- (void)addBody{
    SCNBox *box = [SCNBox boxWithWidth:3 height:3 length:3 chamferRadius:0];
    SCNNode *geoNode = [SCNNode nodeWithGeometry:box];

    box.firstMaterial.multiply.contents = @"pic5.ipg";
    box.firstMaterial.diffuse.contents=@"pic5.ipg";
    box.firstMaterial.multiply.intensity = 0.5;
    box.firstMaterial.lightingModelName =  SCNLightingModelConstant;
    geoNode.position = SCNVector3Make(0, 2, -20);
    [self.scnScene.rootNode addChildNode:geoNode];
    [geoNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];
    [self addFloor];
    [self addLight];
}
  • 相关属性(官方图片)

/**
 创建立方体

 @param width 宽度
 @param height 高度
 @param length 长度
 @param chamferRadius 边的圆角半径
 */
+ (instancetype)boxWithWidth:(CGFloat)width height:(CGFloat)height length:(CGFloat)length chamferRadius:(CGFloat)chamferRadius;

//宽度可动画 默认1
@property(nonatomic) CGFloat width;

//高度可动画 默认1
@property(nonatomic) CGFloat height;

//长度可动画 默认1
@property(nonatomic) CGFloat length;

//圆角半径可动画 默认0
@property(nonatomic) CGFloat chamferRadius;

//沿X轴的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值为1。
@property(nonatomic) NSInteger widthSegmentCount;

//沿Y轴的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值为1。
@property(nonatomic) NSInteger heightSegmentCount;

//沿Z轴的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值为1。
@property(nonatomic) NSInteger lengthSegmentCount;

//圆角的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值是5。
@property(nonatomic) NSInteger chamferSegmentCount;

 

4、SCNPyramid 锥形(金字塔)

  • 效果图

 

  • 相关代码
- (void)addPyramid{
    SCNPyramid *pyramid = [SCNPyramid pyramidWithWidth:5 height:10 length:5];
    SCNNode *geoNode = [SCNNode nodeWithGeometry:pyramid];
    
    pyramid.firstMaterial.multiply.contents = @"pic5.ipg";
    pyramid.firstMaterial.diffuse.contents=@"pic5.ipg";
    pyramid.firstMaterial.multiply.intensity = 0.5;
    pyramid.firstMaterial.lightingModelName =  SCNLightingModelConstant;
    geoNode.position = SCNVector3Make(0, 2, -20);
    [self.scnScene.rootNode addChildNode:geoNode];
    [geoNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];
    [self addFloor];
    [self addLight];
}
  • 相关属性(官方图片)

 

/**
 初始化

 @param width 宽度
 @param height 高度
 @param length 长度
 */
+ (instancetype)pyramidWithWidth:(CGFloat)width height:(CGFloat)height length:(CGFloat)length;

//宽度可动画 默认1
@property(nonatomic) CGFloat width;

//高度可动画 默认1
@property(nonatomic) CGFloat height;

//长度可动画 默认1
@property(nonatomic) CGFloat length;

//沿Z轴的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值为1
@property(nonatomic) NSInteger widthSegmentCount;

//沿Y轴的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值为1
@property(nonatomic) NSInteger heightSegmentCount;

//沿Z轴的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值为1
@property(nonatomic) NSInteger lengthSegmentCount;

 

5、SCNSphere 球体

  • 效果图

  • 相关代码
- (void)addSphere{
    SCNSphere *sphere = [SCNSphere sphereWithRadius:5];
    SCNNode *geoNode = [SCNNode nodeWithGeometry:sphere];
    
    sphere.firstMaterial.multiply.contents = @"pic5.ipg";
    sphere.firstMaterial.diffuse.contents=@"pic5.ipg";
    sphere.firstMaterial.multiply.intensity = 0.5;
    sphere.firstMaterial.lightingModelName =  SCNLightingModelConstant;
    geoNode.position = SCNVector3Make(0, 6, -20);
    [self.scnScene.rootNode addChildNode:geoNode];
    [geoNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];
    [self addFloor];
    [self addLight];
}
  • 相关属性(官方图片)

 

//初始化 球半径
+ (instancetype)sphereWithRadius:(CGFloat)radius;

//半径
@property(nonatomic) CGFloat radius;

//是否用多边形网格来渲染球体 默认NO
@property(nonatomic, getter=isGeodesic) BOOL geodesic;

//沿经纬线的子划分数。可以做成动画。
//如果值小于3,则行为未定义。默认值为24
@property(nonatomic) NSInteger segmentCount;

 

6、SCNCylinder 圆柱

  • 效果图 

  • 相关代码
- (void)addCylinder{
    SCNCylinder *cylinder = [SCNCylinder cylinderWithRadius:6 height:10];
    SCNNode *geoNode = [SCNNode nodeWithGeometry:cylinder];
    
    cylinder.firstMaterial.multiply.contents = @"pic5.ipg";
    cylinder.firstMaterial.diffuse.contents=@"pic5.ipg";
    cylinder.firstMaterial.multiply.intensity = 0.5;
    cylinder.firstMaterial.lightingModelName =  SCNLightingModelConstant;
    geoNode.position = SCNVector3Make(0, 6, -20);
    [self.scnScene.rootNode addChildNode:geoNode];
    [geoNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];
    [self addFloor];
    [self addLight];
}
  • 相关属性(官方图片)

/**
 初始化

 @param radius 圆柱半径
 @param height 高度
 */
+ (instancetype)cylinderWithRadius:(CGFloat)radius height:(CGFloat)height;

//半径
@property(nonatomic) CGFloat radius;

//高度
@property(nonatomic) CGFloat height;

//沿径向坐标的子划分数。可以做成动画。
//如果值小于3,则该行为是未定义的。默认值是48。
@property(nonatomic) NSInteger radialSegmentCount;

//在Y轴上的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值为1。
@property(nonatomic) NSInteger heightSegmentCount;

 

7、SCNCone 圆锥体

  • 效果图

 

  • 相关代码
- (void)addCone{
    SCNCone *cone = [SCNCone coneWithTopRadius:2 bottomRadius:5 height:10];
    SCNNode *geoNode = [SCNNode nodeWithGeometry:cone];
    
    cone.firstMaterial.multiply.contents = @"pic5.ipg";
    cone.firstMaterial.diffuse.contents=@"pic5.ipg";
    cone.firstMaterial.multiply.intensity = 0.5;
    cone.firstMaterial.lightingModelName =  SCNLightingModelConstant;
    geoNode.position = SCNVector3Make(0, 6, -20);
    [self.scnScene.rootNode addChildNode:geoNode];
    [geoNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];
    [self addFloor];
    [self addLight];
}
  • 相关属性(官方图片) 

/**
 初始化

 @param topRadius 顶部半径(顶部为0时就是圆锥)
 @param bottomRadius 底部半径
 @param height 高度
 */
+ (instancetype)coneWithTopRadius:(CGFloat)topRadius bottomRadius:(CGFloat)bottomRadius height:(CGFloat)height;

//顶部半径可动画 默认0
@property(nonatomic) CGFloat topRadius;

//底部半径可动画 默认0.5
@property(nonatomic) CGFloat bottomRadius;

//高度可动画 默认1
@property(nonatomic) CGFloat height;

//沿径向坐标的子划分数。可以做成动画。
//如果值小于3,则该行为是未定义的。默认值是48。
@property(nonatomic) NSInteger radialSegmentCount;

//在Y轴上的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值为1。
@property(nonatomic) NSInteger heightSegmentCount;

 

8、SCNTube 圆柱管道

  • 效果图 

  • 相关代码
- (void)addTube{
    SCNTube *tube = [SCNTube tubeWithInnerRadius:4 outerRadius:5 height:5];
    SCNNode *geoNode = [SCNNode nodeWithGeometry:tube];
    
    tube.firstMaterial.multiply.contents = @"pic5.ipg";
    tube.firstMaterial.diffuse.contents=@"pic5.ipg";
    tube.firstMaterial.multiply.intensity = 0.5;
    tube.firstMaterial.lightingModelName =  SCNLightingModelConstant;
    geoNode.position = SCNVector3Make(0, 6, -20);
    [self.scnScene.rootNode addChildNode:geoNode];
    [geoNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:2 y:0 z:0 duration:1]]];
    [self addFloor];
    [self addLight];
}
  • 相关属性(官方图片)

/**
 初始化

 @param innerRadius 内圆半径
 @param outerRadius 外圆半径
 @param height 高度
 */
+ (instancetype)tubeWithInnerRadius:(CGFloat)innerRadius outerRadius:(CGFloat)outerRadius height:(CGFloat)height;

//内圆半径可动画 默认0.25
@property(nonatomic) CGFloat innerRadius;

//外圆半径可动画 默认0.5
@property(nonatomic) CGFloat outerRadius;

//高度可动画 默认1
@property(nonatomic) CGFloat height;

//沿径向坐标的子划分数。可以做成动画。
//如果值小于3,则该行为是未定义的。默认值是48。
@property(nonatomic) NSInteger radialSegmentCount;

//在Y轴上的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值为1。
@property(nonatomic) NSInteger heightSegmentCount;

 

9、SCNCapsule 胶囊

  • 效果图 

  • 相关代码
- (void)addCapsule{
    SCNCapsule *capsule = [SCNCapsule capsuleWithCapRadius:2 height:10];
    SCNNode *geoNode = [SCNNode nodeWithGeometry:capsule];
    
    capsule.firstMaterial.multiply.contents = @"pic5.ipg";
    capsule.firstMaterial.diffuse.contents=@"pic5.ipg";
    capsule.firstMaterial.multiply.intensity = 0.5;
    capsule.firstMaterial.lightingModelName =  SCNLightingModelConstant;
    geoNode.position = SCNVector3Make(0, 6, -20);
    [self.scnScene.rootNode addChildNode:geoNode];
    [geoNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];
    [self addFloor];
    [self addLight];
}
  • 相关属性(官方图片) 

/**
 初始化

 @param capRadius 球半径
 @param height 高度
 */
+ (instancetype)capsuleWithCapRadius:(CGFloat)capRadius height:(CGFloat)height;

//两端球半径 可动画默认0.5
@property(nonatomic) CGFloat capRadius;

//高度 可动画默认2
@property(nonatomic) CGFloat height;

//沿径向坐标的子划分数。可以做成动画。
//如果值小于3,则该行为是未定义的。默认值是48。
@property(nonatomic) NSInteger radialSegmentCount;

//在Y轴上的子划分数。可以做成动画。
//如果值小于1,则行为未定义。默认值为1。
@property(nonatomic) NSInteger heightSegmentCount;

//帽子上的子划分数。可以做成动画。
//如果值小于2,则行为未定义。默认值是24。
@property(nonatomic) NSInteger capSegmentCount;

 

10、SCNTorus 圆环面

  • 效果图

  • 相关代码
- (void)addToruse{
    SCNTorus *torus = [SCNTorus torusWithRingRadius:4 pipeRadius:1];
    SCNNode *geoNode = [SCNNode nodeWithGeometry:torus];
    
    torus.firstMaterial.multiply.contents = @"pic5.ipg";
    torus.firstMaterial.diffuse.contents=@"pic5.ipg";
    torus.firstMaterial.multiply.intensity = 0.5;
    torus.firstMaterial.lightingModelName =  SCNLightingModelConstant;
    geoNode.position = SCNVector3Make(0, 2, -20);
    [self.scnScene.rootNode addChildNode:geoNode];
    [geoNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];
    [self addFloor];
    [self addLight];
}
  • 相关属性(官方图片)

/**
 初始化

 @param ringRadius 圆环外半径
 @param pipeRadius 圆环半径
 */
+ (instancetype)torusWithRingRadius:(CGFloat)ringRadius pipeRadius:(CGFloat)pipeRadius;

//圆环外半径 可动画默认0.5
@property(nonatomic) CGFloat ringRadius;

//圆环半径 可动画默认0.25
@property(nonatomic) CGFloat pipeRadius;

//环的子划分数。可以做成动画。
//如果值小于3,则该行为是未定义的。默认值是48。
@property(nonatomic) NSInteger ringSegmentCount;

//管子的子划分数。可以做成动画。
//如果值小于3,则该行为是未定义的。默认值是24。
@property(nonatomic) NSInteger pipeSegmentCount;

 

11、SCNFloor 地板

  • 效果图(下面红色就是地板) 

  • 相关代码
- (void)addFloor{
    SCNNode *node = [SCNNode node];
    node.geometry = ({
        SCNFloor *floor = [SCNFloor floor];
        floor.firstMaterial.diffuse.contents = [UIImage imageNamed:@"sun.jpg"];
        floor;
    });
    node.position = SCNVector3Make(0, 0, 0);
    [self.scnScene.rootNode addChildNode:node];
}
  • 相关属性
//初始化
+ (instancetype)floor;

//指定地板的反射率。可以做成动画。
//如果值大于零,则表面将反映场景中的其他对象。默认值为0.25。
@property(nonatomic) CGFloat reflectivity;

//指定从地板开始下降的距离。可以做成动画。默认值为0。
@property(nonatomic) CGFloat reflectionFalloffStart;

//指定从地板上的跌落结束的距离。可以做成动画。
//如果值为0,则没有衰减。默认值为0。
@property(nonatomic) CGFloat reflectionFalloffEnd;

//确定要反射的节点类别
@property(nonatomic) NSUInteger reflectionCategoryBitMask API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0));

//在X轴上的地板范围。可以做成动画。
//如果值等于0,那么在X轴上的地板是无限的。默认值为0。
@property(nonatomic) CGFloat width API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0));

//在Z轴上的地板范围。可以做成动画。
//如果值为0,那么在Z轴上的地板是无限的。默认值为0。
@property(nonatomic) CGFloat length API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0));

//指定用于呈现反射的缓冲区的分辨率比例因子。默认0.5
@property(nonatomic) CGFloat reflectionResolutionScaleFactor API_AVAILABLE(macos(10.10));

 

12、SCNText 字体

  • 效果图

 

  • 相关代码
- (void)addText{
    SCNText *text = [SCNText textWithString:@"你好" extrusionDepth:3];
    text.font = [UIFont systemFontOfSize:8];
    text.alignmentMode = kCAAlignmentCenter;
    SCNNode *geoNode = [SCNNode nodeWithGeometry:text];
    
    text.firstMaterial.multiply.contents = @"pic5.ipg";
    text.firstMaterial.diffuse.contents=@"pic5.ipg";
    text.firstMaterial.multiply.intensity = 0.5;
    text.firstMaterial.lightingModelName =  SCNLightingModelConstant;
    geoNode.position = SCNVector3Make(-8, 0, -20);
    [self.scnScene.rootNode addChildNode:geoNode];
    [self addFloor];
    [self addLight];
}
  • 相关属性(官方图片)

/**
 创建3D文字

 @param string 文本
 @param extrusionDepth 挤压深度
 */
+ (instancetype)textWithString:(nullable id)string extrusionDepth:(CGFloat)extrusionDepth;

//挤压深度 可动画如果值为0就是单面2D版本
@property(nonatomic) CGFloat extrusionDepth;

//文本必须是NSString或NSAttributedString的实例。
@property(nonatomic, copy, nullable) id string;

//字体属性大小 默认值是Helvetica size 36。
@property(nonatomic, retain, null_resettable) UIFont *font;

//文本是否被包装,要包装的文本,首先需要设置它的边界,否则文本不会被包装。默认值是NO。
@property(nonatomic, getter=isWrapped) BOOL wrapped;

//设置文本包装
@property(nonatomic) CGRect containerFrame;

//截断文本以适应边界 枚举默认值kCATruncationNone,具体参考CATextLayer.h
@property(nonatomic, copy) NSString *truncationMode;

//设置文本对齐方式
@property(nonatomic, copy) NSString *alignmentMode;
CA_EXTERN NSString * const kCAAlignmentNatural
CA_AVAILABLE_STARTING (10.5, 3.2, 9.0, 2.0);
CA_EXTERN NSString * const kCAAlignmentLeft
CA_AVAILABLE_STARTING (10.5, 3.2, 9.0, 2.0);
CA_EXTERN NSString * const kCAAlignmentRight
CA_AVAILABLE_STARTING (10.5, 3.2, 9.0, 2.0);
CA_EXTERN NSString * const kCAAlignmentCenter
CA_AVAILABLE_STARTING (10.5, 3.2, 9.0, 2.0);
CA_EXTERN NSString * const kCAAlignmentJustified
CA_AVAILABLE_STARTING (10.5, 3.2, 9.0, 2.0);

//每个倒棱边的宽度或深度。可以做成动画。可以做成动画。
//值范围[0,挤压深度/ 2]。实际的倒角半径可能与此处指定的倒角不同:大的值被剪切到每个字符的最大值。默认值为0。
@property(nonatomic) CGFloat chamferRadius;

//确定每个倒棱边的横截面轮廓的路径。
@property(nonatomic, copy, nullable) UIBezierPath *chamferProfile;

//指定显示字体平滑度
//更小的数字会使曲线更平滑,而在顶点上的计算和更重的几何图形的代价更大。默认值是1.0,它会产生平滑的曲线。
@property(nonatomic) CGFloat flatness API_AVAILABLE(macos(10.9));

 

13、SCNShape 自定义几何体

  • 效果图 

  • 相关代码 
- (void)addPath{
    UIBezierPath *path=[UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0, 0)];
    [path addLineToPoint:CGPointMake(5, 5)];
    [path addLineToPoint:CGPointMake(5, 6)];
    
    [path addArcWithCenter:CGPointMake(2.5, 6) radius:2.5 startAngle:0 endAngle:M_PI clockwise:YES];
    [path addArcWithCenter:CGPointMake(-2.5, 6) radius:2.5 startAngle:0 endAngle:M_PI clockwise:YES];
    [path addLineToPoint:CGPointMake(-5, 5)];
    [path closePath];
    
    //添加路径
    SCNShape *Cylinder = [SCNShape shapeWithPath:path extrusionDepth:6];
    Cylinder.chamferMode =SCNChamferModeBoth;
    Cylinder.firstMaterial.diffuse.contents =[UIImage imageNamed:@"pic5.ipg"];
    SCNNode *geoNode = [SCNNode nodeWithGeometry:Cylinder];
    geoNode.position = SCNVector3Make(0, 0, -20);
    [geoNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];
    [self.scnScene.rootNode addChildNode:geoNode];
    [self addFloor];
    [self addLight];
}
  • 相关属性
//创建并返回给定形状与给定的挤压深度的3D模型
+ (instancetype)shapeWithPath:(nullable UIBezierPath *)path extrusionDepth:(CGFloat)extrusionDepth;

//定义要呈现的形状的路径。
@property(nonatomic, copy, nullable) UIBezierPath *path;

//挤压深度。可以做成动画。
//如果值为0,我们得到一个单面的2D版本的形状。
@property(nonatomic) CGFloat extrusionDepth;

//文本的侧边被倒角。默认值是SCNChamferModeBoth。
@property(nonatomic) SCNChamferMode chamferMode;
typedef NS_ENUM(NSInteger, SCNChamferMode) {
    SCNChamferModeBoth,
    SCNChamferModeFront,
    SCNChamferModeBack
} API_AVAILABLE(macos(10.9));

//倒角半径。可以做成动画。值被夹紧到范围[0,挤压深度/ 2]。默认值为0。
@property(nonatomic) CGFloat chamferRadius;

//描述在“chamferRadius”不是nil时使用的概要文件。当“chamferProfile”为nil时,我们将返回表示象限的路径。
//概要文件应该是一个2D曲线,从(0,1)开始,到(1,0)结束。“平整度”属性也用来使这条路径变平。默认值为nil。
@property(nonatomic, copy, nullable) UIBezierPath *chamferProfile;

 

14、其它相关代码

  • 灯光
- (void)addLight{
    SCNLight *light = [SCNLight light];
    light.type = SCNLightTypeOmni;
    light.color = [UIColor whiteColor];
    self.scnNode.light = light;
}
  • 场景
- (SCNScene *)scnScene{
    if (!_scnScene) {
        _scnScene = [SCNScene scene];
        _scnScene.background.contents = @"Assets.xcassets/pic5.png";
        _scnScene.physicsWorld.gravity = SCNVector3Make(0, -30, 0);
    }
    return _scnScene;
}
  • 根节点
- (SCNNode *)scnNode{
    if (!_scnNode) {
        _scnNode = [[SCNNode alloc] init];
        _scnNode.camera = [[SCNCamera alloc] init];
        _scnNode.camera.zFar = 200.f;
        _scnNode.camera.zNear = .1f;
//        _scnNode.camera.projectionDirection = SCNCameraProjectionDirectionHorizontal;
        _scnNode.position = SCNVector3Make(0, 5, 20);
    }
    return _scnNode;
}
  • 视图view
- (SCNView *)scnView{
    if (!_scnView) {
        _scnView = [[SCNView alloc] initWithFrame:self.view.bounds options:@{SCNViewOptionPreferLowPowerDevice:@"MTLDevice"}];
        _scnView.showsStatistics = YES;
        _scnView.autoenablesDefaultLighting = YES;
        [self.view addSubview:_scnView];
        _scnView.translatesAutoresizingMaskIntoConstraints = NO;
        [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[_scnView]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_scnView)]];
        [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[_scnView]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_scnView)]];
    }
    return _scnView;
}
  • 例子
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.scnView.scene = self.scnScene;
    [self.scnScene.rootNode addChildNode:self.scnNode];
    [self addPath];
}
- (void)addPath{
    UIBezierPath *path=[UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0, 0)];
    [path addLineToPoint:CGPointMake(5, 5)];
    [path addLineToPoint:CGPointMake(5, 6)];
    
    [path addArcWithCenter:CGPointMake(2.5, 6) radius:2.5 startAngle:0 endAngle:M_PI clockwise:YES];
    [path addArcWithCenter:CGPointMake(-2.5, 6) radius:2.5 startAngle:0 endAngle:M_PI clockwise:YES];
    [path addLineToPoint:CGPointMake(-5, 5)];
    [path closePath];
    
    //添加路径
    SCNShape *Cylinder = [SCNShape shapeWithPath:path extrusionDepth:6];
    Cylinder.chamferMode =SCNChamferModeBoth;
    Cylinder.firstMaterial.diffuse.contents =[UIImage imageNamed:@"pic5.ipg"];
    SCNNode *geoNode = [SCNNode nodeWithGeometry:Cylinder];
    geoNode.position = SCNVector3Make(0, 0, -20);
    [geoNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];
    [self.scnScene.rootNode addChildNode:geoNode];
    [self addFloor];
    [self addLight];
}

 

posted @ 2018-05-08 10:03  ForeverGuard  阅读(1781)  评论(0编辑  收藏  举报