我有一个KUKA机器人模型的DAE格式转换从步骤。该模型由材质(只是平面颜色)分割成根节点的子节点。例如,所有被认为是机器人手臂的部件都作为一个单一的几何物体被包括在一起,并应用绿色材料。底层元素是一个大的三角形条带。
我需要把机器人的所有部分分开,这样我才能正确地动画它们。在我计划分离的大部分部分之间都有视觉上的空白。我的第一个想法是寻找三角形条带中的缺口,但我不知道如何知道缺口在哪里。(推论:三角带怎么会有缺口?)
第二个想法是选择要呈现的元素范围(我认为是二进制搜索风格,手动调整数字或使用屏幕上的控件)。这将是最有用的地方,几何学是视觉相邻,但部分需要分开。
问题1:是否有一种方法来确定三角带的间隙在哪里?
问题2:是否存在用于选择要呈现的元素子集的API?写这个当然是可能的,但看起来要做很多工作(选择元素、相关的源、纹理映射可能很快就会出来.)
发布于 2014-12-02 02:41:30
虽然mnuages的答案为标题提供了一个合适的答案(实际上是“隐藏”几何图形的部分),但我意识到这是不够的,因为我希望以编程方式将剩余的几何图形序列化为场景中的一个节点。
为了回答我的“问题2",我在SceneKit类中添加了一些内容,这样我就可以从原始对象生成新的SCNGeometry对象。对于材料(我的模型使用简单的颜色;这段代码可能还不能正确处理其他纹理);它可能不适用于三角形条以外的原语。
该代码在GitHub中可在https://github.com/Fyrestead/PartialGeometry上使用。
为了完整起见,初始版本贴在下面。
SCNGeometry加法:
//
// 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加法:
//
// 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加法:
//
// 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
}
}发布于 2014-11-28 17:00:21
SceneKit不提供检查网格拓扑和检测漏洞的工具。如果您的原始模型没有这些空白,那么应该尝试在您的步骤中找到DAE转换器的问题。
没有方便的方法只绘制几何图形的一些元素。创建一个新的几何学只是你感兴趣的元素相当容易。如果您想要快速和肮脏的东西,您还可以编写一个SCNProgram,它在顶点着色器中什么都不做,并在片段着色器中丢弃片段。根据您的需要创建一系列的材料,并将其设置为几何学。
https://stackoverflow.com/questions/27135364
复制相似问题