首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确使用NSImage作为SCNGeometry形状的材质?

如何正确使用NSImage作为SCNGeometry形状的材质?
EN

Stack Overflow用户
提问于 2019-04-27 22:47:57
回答 2查看 190关注 0票数 1

我在大学里接到一个任务,要给SCNGeometry八面体添加一张图片作为纹理。这是我在Swift的第一个项目。

关于带有UIImage的UIKit类有很多建议,但我使用的是AppKit for macos和NSImage类。我在网络上找到的选择没有一个对我不起作用。也许我误解了一些基本的东西。首先,我将一张名为"sims.jpg“的图片拖放到我的项目文件夹和art.scnassets文件夹中。并添加他们与文件和添加文件到"art.scnassets“和一般文件夹。对Assets.xcassets什么都没做。

下面是该形状的创建方式:

代码语言:javascript
复制
func createOctahedron() {

   let vertices: [SCNVector3] = [
       SCNVector3(0, 1, 0),
       SCNVector3(-0.5, 0, 0.5),
       SCNVector3(0.5, 0, 0.5),
       SCNVector3(0.5, 0, -0.5),
       SCNVector3(-0.5, 0, -0.5),
       SCNVector3(0, -1, 0)
   ]

   let source = SCNGeometrySource(vertices: vertices)

   let indices: [UInt16] = [
       0, 1, 2,
       2, 3, 0,
       3, 4, 0,
       4, 1, 0,
       1, 5, 2,
       2, 5, 3,
       3, 5, 4,
       4, 5, 1
   ]

   let element = SCNGeometryElement(indices: indices, primitiveType: .triangles)
   let geometry = SCNGeometry(sources: [source], elements: [element])
   let node = SCNNode(geometry: geometry)

   node.geometry?.firstMaterial?.diffuse.contents = NSColor.green // назначаем цвет октаэдру

   let scnView = self.view as! SCNView
   scnView.scene?.rootNode.addChildNode(node)

   let rotateAction = SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: .pi, z: 0, duration: 5))
   node.runAction(rotateAction)
}

为了以防万一,让我留下一个full code

因此,我会像这样添加图像

代码语言:javascript
复制
let imageMaterial = SCNMaterial()
let image = NSImage.Name("sims")
imageMaterial.diffuse.contents = image
geometry.materials = [imageMaterial, imageMaterial, imageMaterial, imageMaterial, imageMaterial, imageMaterial, imageMaterial, imageMaterial]

或者像这样?

代码语言:javascript
复制
node.geometry?.firstMaterial?.diffuse.contents = NSImage.Name("sims")

或者我应该以某种方式额外映射它?请帮帮我,因为我真的不明白。Xcode只输出一个旋转的八面体,没有额外的纹理,也没有错误

EN

回答 2

Stack Overflow用户

发布于 2019-04-28 03:39:42

下面这一行:

代码语言:javascript
复制
let image = NSImage.Name("sims")

仅声明名称。您需要:

代码语言:javascript
复制
let image = NSImage(named: NSImage.Name("sims"))

编译代码的原因是contents属性具有Any?类型,因此您可以在该属性中放置任何旧的粘性对象。它会静悄悄地失败。

票数 1
EN

Stack Overflow用户

发布于 2019-05-04 20:00:16

我知道交易是怎么回事了。由于没有UV映射,因此没有显示纹理。我应该在CGPoint的帮助下在段0,1上声明一个二维坐标数组,然后将它添加到source数组中。

下面是它的大致外观:

代码语言:javascript
复制
         let width:CGFloat = 1/8
         let coordinates: [CGPoint] = [
         CGPoint(x: 0,     y: 0),// BAC
         CGPoint(x: width, y: 0),
         CGPoint(x: width, y: 1),
         CGPoint(x: 0,     y: 1),// BAE
         CGPoint(x: width * 7, y: 0),
         CGPoint(x: 1,         y: 0),
         CGPoint(x: 1,         y: 1),// EDA
         CGPoint(x: width * 7, y: 1),
         CGPoint(x: width * 6, y: 0),
         CGPoint(x: width * 7, y: 0),// DAC
         CGPoint(x: width,     y: 0),
         CGPoint(x: width * 4, y: 0),
         CGPoint(x: width * 7, y: 1),// DFC
         CGPoint(x: width * 6, y: 1),
         CGPoint(x: width * 4, y: 1),
         CGPoint(x: width,     y: 1),// BFC
         CGPoint(x: width * 4, y: 0),
         CGPoint(x: width * 5, y: 0),
         CGPoint(x: width * 5, y: 1),// BFE
         CGPoint(x: width * 6, y: 1),
         CGPoint(x: width * 5, y: 0),
         CGPoint(x: width * 6, y: 0),// EFD
         CGPoint(x: width * 4, y: 1),
         CGPoint(x: width * 5, y: 1),
         ]

        let source = [
            SCNGeometrySource(vertices: vertices),
            SCNGeometrySource(textureCoordinates: coordinates)
        ]
        let element = SCNGeometryElement(indices: indices, primitiveType: .triangles)

        let octahedron = SCNGeometry(sources: source, elements: [element])

在我们指定坐标之后,编写以下代码就足够了:

代码语言:javascript
复制
        let image = NSImage(named: NSImage.Name("sims"))
        octahedron.firstMaterial?.diffuse.contents = image

图像将被拉伸到我们的八面体的面上。full code附加

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55881717

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档