首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >显示拉伸材料在SCNGeometrySource节点上的应用

显示拉伸材料在SCNGeometrySource节点上的应用
EN

Stack Overflow用户
提问于 2019-06-26 06:30:21
回答 1查看 421关注 0票数 1

我已经创建了SCNNode使用自定义选择的SCNVector3点超过三个使用SCNGeometrySource和应用图像材料显示非常拉伸的材料。如何在SCNGeometrySource节点上正确应用材料。

代码语言:javascript
复制
func getsquareDrawnLineFrom(pos1: SCNVector3,
                            pos2: SCNVector3,
                            pos3: SCNVector3) -> SCNNode {

    let square = SquareplanlineFrom(vector1: pos1, vector2: pos2, vector3: pos3)
    //SCNGeometrySource.Semantic.texcoord
    //SCNGeometrySource.Semantic.normal
    let material = SCNMaterial()
    // material.diffuse.contents = UIColor.lightGray
    material.diffuse.contents = UIImage(named: "grid")
    material.diffuse.contentsTransform = SCNMatrix4MakeScale(32, 32, 0)
    material.diffuse.wrapS = .repeat
    material.diffuse.wrapT = .repeat
    square.materials = [material]
    let square1 = SCNNode(geometry: square)
    square1.name = "tringle"
    return square1
}

// get line geometry between two vectors
func SquareplanlineFrom(vector1: SCNVector3,
              vector2: SCNVector3, vector3: SCNVector3) -> SCNGeometry {
     let normalsPerFace = 3
    let indices: [Int32] = [0, 1, 2]
    let source = SCNGeometrySource(vertices: [vector1, vector2, vector3])
    let normals:[SCNVector3] = [
        vector1,
        vector2,
        vector3].map{[SCNVector3](repeating:$0,count:normalsPerFace)}.flatMap{$0}
    let normalSource = SCNGeometrySource(normals: normals)
    let cgp1 = CGPoint(x: CGFloat(vector1.x), y: CGFloat(vector1.y))
    let cgp2 = CGPoint(x: CGFloat(vector2.x), y: CGFloat(vector2.y))
    let cgp3 = CGPoint(x: CGFloat(vector3.x), y: CGFloat(vector3.y))
    let textcoord = SCNGeometrySource(textureCoordinates: [cgp1,cgp2,cgp3])

    // let texcoord = SCNGeometrySource(textureCoordinates: [])
    // let normalSource = SCNGeometrySource(normals: [vector1, vector2, vector3])

    let element = SCNGeometryElement(indices: indices,
                                     primitiveType: .triangles)
    return SCNGeometry(sources: [source,normalSource,textcoord], elements: [element])
}

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-26 07:52:59

纹理的比例问题:

我不知道你的模型的大小,但我认为问题是-你增加了一个规模,虽然你必须缩小它,以正确地映射一个纹理。

我的纹理大小是2K平方(2048x2048,72dpi)。

下面是一个代码(这里我使用了macOS版本):

代码语言:javascript
复制
internal func getFaceDrawnFrom(pos1: SCNVector3,
                               pos2: SCNVector3,
                               pos3: SCNVector3) -> SCNNode {

    let triGeo = generateGeoFrom(vector1: pos1,
                                 vector2: pos2,
                                 vector3: pos3)

    let material = SCNMaterial()
    material.diffuse.contents = NSImage.Name("art.scnassets/jaguar.jpg")

    // your scale
    // material.diffuse.contentsTransform = SCNMatrix4MakeScale(32, 32, 0)

    material.isDoubleSided = true

    material.diffuse.contentsTransform = .init(
                                     m11: 0.05, m12: 0,    m13: 0,    m14: 0,
                                     m21: 0,    m22: 0.05, m23: 0,    m24: 0,
                                     m31: 0,    m32: 0,    m33: 1,    m34: 0,
                                     m41: 0,    m42: 0,    m43: 0,    m44: 1)
    material.diffuse.wrapS = .repeat
    material.diffuse.wrapT = .repeat
    square.materials = [material]

    let node = SCNNode(geometry: triGeo)
    node.name = "triangularFace"
    scene.rootNode.addChildNode(node)
    return node
}

然后:

代码语言:javascript
复制
fileprivate func generateGeoFrom(vector1: SCNVector3,
                                 vector2: SCNVector3,
                                 vector3: SCNVector3) -> SCNGeometry {

    let normalsPerFace = 3
    let indices: [Int32] = [0, 1, 2]
    let source = SCNGeometrySource(vertices: [vector1, vector2, vector3])

    let vecs = [vector1, vector2, vector3].map { 
        [SCNVector3](repeating: $0, count: normalsPerFace) 
    }.flatMap { $0 }

    let normals: [SCNVector3] = vecs

    let normalSource = SCNGeometrySource(normals: normals)
    let cgp1 = CGPoint(x: CGFloat(vector1.x), y: CGFloat(vector1.y))
    let cgp2 = CGPoint(x: CGFloat(vector2.x), y: CGFloat(vector2.y))
    let cgp3 = CGPoint(x: CGFloat(vector3.x), y: CGFloat(vector3.y))
    let textcoord = SCNGeometrySource(textureCoordinates: [cgp1, cgp2, cgp3])
        
    let element = SCNGeometryElement(indices: indices,
                               primitiveType: .triangles)

    return SCNGeometry(sources: [source, normalSource, textcoord], 
                      elements: [element])
}

那么让我们调用这个方法。

代码语言:javascript
复制
let instance = getFaceDrawnFrom(pos1: SCNVector3(x: 0, y: 0, z: 0),
                                pos2: SCNVector3(x: 8, y: 5, z: 0),
                                pos3: SCNVector3(x:-8, y: 5, z: 0))

法线方向问题

通常一个模型每个三角形面有3个法线,换句话说,每个面的每个顶点都有一个法线。法线必须垂直于表面,而不是平行的。如果你有问题的表面法线,那么你将无法点燃模型。

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

https://stackoverflow.com/questions/56766516

复制
相关文章

相似问题

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