首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >把三角形藏在三角地带里?(以编程方式隐藏模型的部分)

把三角形藏在三角地带里?(以编程方式隐藏模型的部分)
EN

Stack Overflow用户
提问于 2014-11-25 19:46:20
回答 2查看 597关注 0票数 1

我有一个KUKA机器人模型的DAE格式转换从步骤。该模型由材质(只是平面颜色)分割成根节点的子节点。例如,所有被认为是机器人手臂的部件都作为一个单一的几何物体被包括在一起,并应用绿色材料。底层元素是一个大的三角形条带。

我需要把机器人的所有部分分开,这样我才能正确地动画它们。在我计划分离的大部分部分之间都有视觉上的空白。我的第一个想法是寻找三角形条带中的缺口,但我不知道如何知道缺口在哪里。(推论:三角带怎么会有缺口?)

第二个想法是选择要呈现的元素范围(我认为是二进制搜索风格,手动调整数字或使用屏幕上的控件)。这将是最有用的地方,几何学是视觉相邻,但部分需要分开。

问题1:是否有一种方法来确定三角带的间隙在哪里?

问题2:是否存在用于选择要呈现的元素子集的API?写这个当然是可能的,但看起来要做很多工作(选择元素、相关的源、纹理映射可能很快就会出来.)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-02 02:41:30

虽然mnuages的答案为标题提供了一个合适的答案(实际上是“隐藏”几何图形的部分),但我意识到这是不够的,因为我希望以编程方式将剩余的几何图形序列化为场景中的一个节点。

为了回答我的“问题2",我在SceneKit类中添加了一些内容,这样我就可以从原始对象生成新的SCNGeometry对象。对于材料(我的模型使用简单的颜色;这段代码可能还不能正确处理其他纹理);它可能不适用于三角形条以外的原语。

该代码在GitHub中可在https://github.com/Fyrestead/PartialGeometry上使用。

为了完整起见,初始版本贴在下面。

SCNGeometry加法:

代码语言:javascript
复制
//
//  SCNGeometry.swift
//
//  Created by Shon Frazier on 11/22/14.
//  Copyright (c) 2014 Fyrestead, LLC. All rights reserved.
//

import Foundation
import SceneKit

let allSemantics = [
    SCNGeometrySourceSemanticVertex,
    SCNGeometrySourceSemanticNormal,
    SCNGeometrySourceSemanticColor,
    SCNGeometrySourceSemanticTexcoord,
    SCNGeometrySourceSemanticVertexCrease,
    SCNGeometrySourceSemanticEdgeCrease,
    SCNGeometrySourceSemanticBoneWeights,
    SCNGeometrySourceSemanticBoneIndices
]


extension SCNGeometry {

    func geometryForRangeOfPrimitives(range: NSRange) -> SCNGeometry? {

        var primitiveType: SCNGeometryPrimitiveType

        var allElements: [SCNGeometryElement] = [SCNGeometryElement]()

        for i in 0..<self.geometryElementCount {
            let element = self.geometryElementAtIndex(i)
            if element == nil {
                continue
            }

            var newElement = element!.geometryElementForRangeOfPrimitives(range)

            if newElement != nil {
                allElements += [newElement!]
            }
        }


        var allSources: [SCNGeometrySource] = [SCNGeometrySource]()

        for semantic in allSemantics {
            var sources = self.geometrySourcesForSemantic(semantic)
            if sources == nil {
                continue
            }

            for source in sources! as [SCNGeometrySource] {
                var range: NSRange = NSRange(location: 0, length: 5)

                let newSource = source.geometrySourceForRangeOfPrimitives(range, primitiveType: SCNGeometryPrimitiveType.TriangleStrip)

                allSources += [newSource!]
            }
        }


        var newGeometry = SCNGeometry(sources: allSources, elements: allElements)
        newGeometry.materials = materials

        return newGeometry
    }
}

SCNGeometryElement加法:

代码语言:javascript
复制
//
//  SCNGeometryElement.swift
//
//  Created by Shon Frazier on 11/23/14.
//  Copyright (c) 2014 Fyrestead, LLC. All rights reserved.
//

import Foundation
import SceneKit

extension SCNGeometryElement {

    func geometryElementForRangeOfPrimitives(range: NSRange) -> SCNGeometryElement? {

        if data == nil {
            return nil
        }

        let newCount = range.length
        let newLocation = range.location * bytesPerIndex
        let newLength = range.length * bytesPerIndex
        let newRange = NSRange(location: newLocation, length: newLength)
        let newData = data!.subdataWithRange(newRange)

        let newElement = SCNGeometryElement(
            data: newData,
            primitiveType: primitiveType,
            primitiveCount: newCount,
            bytesPerIndex: bytesPerIndex
        )

        return newElement
    }

}

SCNGeometrySource加法:

代码语言:javascript
复制
//
//  SCNGeometrySource.swift
//
//  Created by Shon Frazier on 11/23/14.
//  Copyright (c) 2014 Fyrestead, LLC. All rights reserved.
//

import Foundation
import SceneKit

extension SCNGeometrySource {

    /* Preserves use of existing data buffer by changing only the offset */
    func geometrySourceForRangeOfVectors(range: NSRange) -> SCNGeometrySource? {

        if data == nil {
            return nil
        }

        let newOffset = dataOffset + range.location * (dataStride + bytesPerComponent * componentsPerVector)

        return SCNGeometrySource(
            data: data!,
            semantic: semantic,
            vectorCount: range.length,
            floatComponents: floatComponents,
            componentsPerVector: componentsPerVector,
            bytesPerComponent: bytesPerComponent,
            dataOffset: newOffset,
            dataStride: dataStride)
    }

    func geometrySourceForRangeOfPrimitives(range: NSRange, primitiveType: SCNGeometryPrimitiveType) -> SCNGeometrySource? {

        var newGSource: SCNGeometrySource?

        switch primitiveType {
        case .TriangleStrip, .Point:
            newGSource = geometrySourceForRangeOfVectors(range)

        case .Triangles:
            let newRange = NSRange(location: range.location * 3, length: range.length * 3)
            newGSource = geometrySourceForRangeOfVectors(newRange)

        case .Line:
            let newRange = NSRange(location: range.location * 2, length: range.length * 2)
            newGSource = geometrySourceForRangeOfVectors(newRange)
        }

        return newGSource
    }

}
票数 0
EN

Stack Overflow用户

发布于 2014-11-28 17:00:21

SceneKit不提供检查网格拓扑和检测漏洞的工具。如果您的原始模型没有这些空白,那么应该尝试在您的步骤中找到DAE转换器的问题。

没有方便的方法只绘制几何图形的一些元素。创建一个新的几何学只是你感兴趣的元素相当容易。如果您想要快速和肮脏的东西,您还可以编写一个SCNProgram,它在顶点着色器中什么都不做,并在片段着色器中丢弃片段。根据您的需要创建一系列的材料,并将其设置为几何学。

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

https://stackoverflow.com/questions/27135364

复制
相关文章

相似问题

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